From: Michael Tremer Date: Mon, 18 Jul 2022 16:17:38 +0000 (+0000) Subject: backend: Move running background tasks into backend X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fcffdb60279a8110d6b1a40b6fae0de229a941b9;p=pbs.git backend: Move running background tasks into backend Signed-off-by: Michael Tremer --- diff --git a/src/buildservice/__init__.py b/src/buildservice/__init__.py index 925b1321..dbe7e568 100644 --- a/src/buildservice/__init__.py +++ b/src/buildservice/__init__.py @@ -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): diff --git a/src/hub/__init__.py b/src/hub/__init__.py index 6184406f..d8291d9d 100644 --- a/src/hub/__init__.py +++ b/src/hub/__init__.py @@ -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)