]> git.ipfire.org Git - pbs.git/commitdiff
backend: Move running background tasks into backend
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 18 Jul 2022 16:17:38 +0000 (16:17 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 18 Jul 2022 16:17:38 +0000 (16:17 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/buildservice/__init__.py
src/hub/__init__.py

index 925b1321b8d58d0b87efd4cb6d11578c0bc91f5a..dbe7e5683afa3d09d08b9e64652837aaa5ca3c61 100644 (file)
@@ -2,6 +2,7 @@
 
 import asyncio
 import configparser
+import inspect
 import logging
 import os
 import pakfire
@@ -44,6 +45,9 @@ from .constants import *
 class Backend(object):
        version = __version__
 
+       # A list of any background tasks
+       __tasks = set()
+
        def __init__(self, config_file=None):
                # Read configuration file.
                self.config = self.read_config(config_file)
@@ -161,6 +165,48 @@ class Backend(object):
                        # Delete the configuration file
                        os.unlink(t)
 
+       # Functions to run something in background
+
+       def run_task(self, callback, *args):
+               """
+                       Runs the given coroutine in the background
+               """
+               # Create a new task
+               task = asyncio.create_task(callback(*args))
+
+               # Keep a reference to the task and remove it when the task has finished
+               self.__tasks.add(task)
+               task.add_done_callback(self.__tasks.discard)
+
+               return task
+
+       def run_periodic_task(self, delay, callback, *args):
+               """
+                       Calls the given callback periodically in the background
+               """
+               self.run_task(self._periodic_task, delay, callback, *args)
+
+       async def _periodic_task(self, delay, callback, *args):
+               """
+                       Helper function for run_periodic_task() that will call the given
+                       callback regulary after the timer has expired.
+               """
+               log.debug("Periodic callback %r started" % callback)
+
+               while True:
+                       # Wait a little moment
+                       await asyncio.sleep(delay)
+
+                       try:
+                               ret = callback(*args)
+
+                               # Await ret if callback is a coroutine
+                               if inspect.isawaitable(ret):
+                                       await ret
+
+                       except Exception as e:
+                               log.error("Exception in periodic callback %r" % callback, exc_info=True)
+
        # Commands
 
        async def command(self, *args, krb5_auth=False, **kwargs):
index 6184406f17a7198c40b4a5580f8b6e07d8559909..d8291d9d065cbc29b46c23adf0e857c0d532895b 100644 (file)
@@ -49,26 +49,10 @@ class Application(tornado.web.Application):
                self.backend = Backend()
 
                # Launch any background jobs
-               self._run_task(queue.dispatch_jobs, 5)
+               self.backend.run_periodic_task(5, queue.dispatch_jobs, self.backend)
 
                logging.info("Successfully initialied application")
 
                # Perform some initial tasks
-               self._run_task(self.backend.builders.sync)
-               self._run_task(self.backend.builders.autoscale)
-
-       def _run_task(self, callback, t=None):
-               """
-                       Runs the callback every t seconds in the background or once if t is None
-               """
-               # Pass backend to the function
-               callback = functools.partial(callback, self.backend)
-
-               # Create a periodic callback object
-               if t:
-                       task = tornado.ioloop.PeriodicCallback(callback, t * 1000)
-                       task.start()
-
-               else:
-                       ioloop = tornado.ioloop.IOLoop.current()
-                       ioloop.add_callback(callback)
+               self.backend.run_task(self.backend.builders.sync)
+               self.backend.run_task(self.backend.builders.autoscale)