]> git.ipfire.org Git - pbs.git/commitdiff
builders: Create a new kind of control connection
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 26 Apr 2023 10:35:21 +0000 (10:35 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 26 Apr 2023 10:35:21 +0000 (10:35 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/buildservice/builders.py
src/web/__init__.py
src/web/base.py
src/web/builders.py

index 8d47f9bfb20bc768989121606b907d7791700d4d..945af1a5ec07fb955ea658c4371716712f62d354 100644 (file)
@@ -13,6 +13,9 @@ from .decorators import *
 log = logging.getLogger("pbs.builders")
 
 class Builders(base.Object):
+       # Stores any control connections to builders
+       connections = {}
+
        def _get_builder(self, query, *args):
                res = self.db.get(query, *args)
 
@@ -204,16 +207,11 @@ class Builder(base.DataObject):
                """
                        Returns True if the builder is online
                """
-               if self.stats:
+               if self.connection:
                        return True
 
                return False
 
-       def set_online_until(self, online_until):
-               self._set_attribute("online_until", online_until)
-
-       online_until = property(lambda s: s.data.online_until, set_online_until)
-
        def log_stats(self, cpu_model=None, cpu_count=None, cpu_arch=None, pakfire_version=None,
                        os_name=None, cpu_user=None, cpu_nice=None, cpu_system=None, cpu_idle=None,
                        cpu_iowait=None, cpu_irq=None, cpu_softirq=None, cpu_steal=None, cpu_guest=None,
@@ -441,19 +439,6 @@ class Builder(base.DataObject):
        def host_key_id(self):
                return self.data.host_key_id
 
-       @property
-       def state(self):
-               if not self.enabled:
-                       return "disabled"
-
-               if self.data.time_keepalive is None:
-                       return "offline"
-
-               #if self.data.updated >= 5*60:
-               #       return "offline"
-
-               return "online"
-
        def is_ready(self):
                # If the builder is not enabled, we are obviously not ready
                if not self.enabled:
@@ -631,3 +616,42 @@ class Builder(base.DataObject):
                )
 
                return res.t
+
+       # Connections
+
+       def connected(self, connection):
+               """
+                       Called when a builder has connected
+               """
+               # Replace any old connections
+               if self.connection:
+                       log.warning("Closing connection to %s because it is being replaced" % self)
+
+                       # Close the previous connection
+                       self.connection.close(code=1000, reason="Replaced by a new connection")
+
+               log.debug("%s has connected" % self)
+
+               # Store the connection
+               self.backend.builders.connections[self] = connection
+
+       def disconnected(self):
+               """
+                       Called when a builder has disconnected
+               """
+               log.debug("%s has disconnected" % self)
+
+               try:
+                       del self.backend.builders.connections[self]
+               except IndexError:
+                       pass
+
+       @property
+       def connection(self):
+               """
+                       Easy access to the control connection to a builder
+               """
+               try:
+                       return self.backend.builders.connections[self]
+               except KeyError:
+                       pass
index f877a791bda26f0e06f66428795e69a087bda424..ae0ec960812f43afebc74e89c2e1e5d68fc8befd 100644 (file)
@@ -151,7 +151,7 @@ class Application(tornado.web.Application):
                        (r"/builders/([A-Za-z0-9\-\.]+)/delete", builders.BuilderDeleteHandler),
                        (r"/builders/([A-Za-z0-9\-\.]+)/edit", builders.BuilderEditHandler),
                        (r"/builders/([A-Za-z0-9\-\.]+)", builders.BuilderDetailHandler),
-                       (r"/api/v1/builders/stats", builders.APIv1StatsHandler),
+                       (r"/api/v1/builders/control", builders.APIv1ControlHandler),
 
                        # Distributions
                        (r"/distros", distributions.IndexHandler),
index 77d79775439c755aef874bfe885cc6f983b6f161..271040ee9007fa3b2c8a09da5412eb2d442326ad 100644 (file)
@@ -313,6 +313,16 @@ class APIMixin(KerberosAuthMixin, BackendMixin):
        def get_user_locale(self):
                return self.get_browser_locale()
 
+       @property
+       def builder(self):
+               """
+                       This is a convenience handler to access a builder by a better name
+               """
+               if isinstance(self.current_user, builders.Builder):
+                       return self.current_user
+
+               raise AttributeError
+
        def write_error(self, code, **kwargs):
                # Send a JSON-encoded error message
                self.finish({
index f9606dbd831ce7a851f6099546d0e2c13f7bd83f..a0c3e16a5182c6104b9a08288bf9edd3412108f2 100644 (file)
@@ -4,31 +4,25 @@ import tornado.web
 
 from . import base
 
-class APIv1StatsHandler(base.APIMixin, tornado.websocket.WebSocketHandler):
+class APIv1ControlHandler(base.APIMixin, tornado.websocket.WebSocketHandler):
        @tornado.web.authenticated
-       def __open(self):
-               args = {
-                       # CPU info
-                       "cpu_model"       : self.get_argument("cpu_model", None),
-                       "cpu_count"       : self.get_argument("cpu_count", None),
-                       "cpu_arch"        : self.get_argument("cpu_arch", None),
-
-                       # Pakfire
-                       "pakfire_version" : self.get_argument("pakfire_version", None),
-
-                       # OS
-                       "os_name"         : self.get_argument("os_name", None),
-               }
-
-               with self.db.transaction():
-                       self.builder.update_info(**args)
-
-       def on_message(self, message):
-               # Decode message
-               message = self._decode_json_message(message)
-
-               with self.db.transaction():
-                       self.current_user.log_stats(**message)
+       async def open(self):
+               # The builder has opened a new connection
+               self.current_user.connected(self)
+
+               # After the builder has connected, try to dispatch some jobs
+               await self.backend.jobqueue.dispatch_jobs()
+
+       def on_close(self):
+               # Drop the connection to the builder
+               self.current_user.disconnected()
+
+       #def on_message(self, message):
+       #       # Decode message
+       #       message = self._decode_json_message(message)
+       #
+       #       with self.db.transaction():
+       #               self.current_user.log_stats(**message)
 
 
 class BuilderListHandler(base.BaseHandler):