Пример #1
0
    def __init__(self, sched, prefix):
        """ClientRegistry Constructor.

        Args:
            sched: A scheduler.Scheduler instance.

            prefix: The base path where the store will be created/read.
        """
        resource.Resource.__init__(self)
        # Set things up
        self.scheduler = sched
        self.store_path = prefix + "/clients/"
        # Setup/restore persistent storage for client information
        if not os.path.isdir(self.store_path):
            os.makedirs(self.store_path)
        self.known_clients = DirDBM(self.store_path)
        # Restore information about jobs done
        self.jobs_done = {}
        for client_id in self.known_clients.keys():
            num_jobs_done = int(self.known_clients[client_id].split("#")[4])
            self.jobs_done[client_id] = num_jobs_done
Пример #2
0
class ClientRegistry(resource.Resource):
    """Keeps information about the clients that contacted this server.

    Besides storing information about our peers (clients), this class also
    provides a page (resource) from with information about our clients (name,
    ID, IP, number of jobs completed) can be gathered.

    Information about client is stored in a DirDBM. For a given client ID,
    we store it's CLIENT_SENT_HEADERS headers and the # of jobs performed.
    Information is stored as a string, fields separated by '#'.
    """

    isLeaf = True

    CLIENT_SENT_HEADERS = ['client-id', 'client-hostname', 'client-version', \
                           'client-arver']

    HTML_HEADER = """<html>
        <head>
            <title>Client Status</title>
            <link href="./static/style.css" type="text/css" rel="stylesheet" />
            <script type="text/javascript" src="./static/sortable.js"></script>
        </head>
        <body>
        <h1>Clients</h1>
        <table class="sortable" id="clientState">
         <thead>
           <tr>
             <th>client-hostname</th><th>client-version</th>
             <th>client-arver</th><th># jobs</th><th>state</th><th>Next job</th>
           </tr>
         <thead>
         <tbody>"""

    HTML_FOOTER = """</tbody></table>
        </body>
        </html> """

    def __init__(self, sched, prefix):
        """ClientRegistry Constructor.

        Args:
            sched: A scheduler.Scheduler instance.

            prefix: The base path where the store will be created/read.
        """
        resource.Resource.__init__(self)
        # Set things up
        self.scheduler = sched
        self.store_path = prefix + "/clients/"
        # Setup/restore persistent storage for client information
        if not os.path.isdir(self.store_path):
            os.makedirs(self.store_path)
        self.known_clients = DirDBM(self.store_path)
        # Restore information about jobs done
        self.jobs_done = {}
        for client_id in self.known_clients.keys():
            num_jobs_done = int(self.known_clients[client_id].split("#")[4])
            self.jobs_done[client_id] = num_jobs_done

    def updateClientStats(self, request, job_done=False):
        """Updates information about a client and retrieve its id.

        This method should be called by Task Controllers in order to keep our
        knowledge about clients fresh and correct.

        Args:
            request: The request object passed by the twisted framework. Client
                identification will be extracted from it.

            job_done: Was a task/job completed by this client? Pass True if so,
                or False if this was just a ping or something related.

        @return client's client_id.
        """
        client_id = request.getHeader('client-id')
        if client_id is None:
            raise InvalidClientId()
        if job_done:
            self.jobs_done[client_id] = self.jobs_done.get(client_id, 0) + 1
        # store client information in persistent storage
        client_data = []
        for hdr in self.CLIENT_SENT_HEADERS:
            content = request.getHeader(hdr)
            if not content:
                content = 'UNKNOWN'
            client_data.append(content)
        client_data.append(str(self.jobs_done.get(client_id, 0)))
        self.known_clients[client_id] = "#".join(client_data)

        return client_id

    def render(self, _request):
        """Render HTML code for the client status page."""
        now = time.time()
        result = []
        result.append(self.HTML_HEADER)
        for client_id in self.known_clients.keys():
            # get client status
            last_seen = self.scheduler.peers.get(client_id)
            if last_seen:
                state = 'ALIVE'
            else:
                state = 'DEAD'
                last_seen = now + 1 # Avoid a (None - Float) subtracion bellow
            # print client data
            result.append('<tr class="%s" id="%s">' % (state, client_id))
            for val in self.known_clients[client_id].split("#")[1:]:
                result.append('<td>%s</td>' % val)

            result.append('<td>%s</td>' % state)
            result.append('<td>%i</td>' % (now - last_seen))
            result.append('</tr>')
        result.append(self.HTML_FOOTER)
        return "".join(result)