From 91969dbfbbb46f836622ee56d30fd698cf4f02a2 Mon Sep 17 00:00:00 2001 From: "Piotr F. Mieszkowski" Date: Sat, 29 Oct 2022 16:09:24 +0200 Subject: [PATCH] Re-use the same Event Loop for each coroutine Function asyncio.run creates a new event loop each time it's called and executes coroutine in that new loop. However, we want all our coroutines to be executed from the same event loop, so we acquire a loop when lacre.daemon starts and then use it to execute them later. See: Disroot/gpg-lacre#109 --- lacre/daemon.py | 8 ++++++-- lacre/keyring.py | 8 +++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lacre/daemon.py b/lacre/daemon.py index 9607ecb..2df9d06 100644 --- a/lacre/daemon.py +++ b/lacre/daemon.py @@ -47,6 +47,9 @@ class MailEncryptionProxy: except TypeError as te: LOG.exception("Got exception while processing", exc_info=te) return RESULT_ERROR + except: + LOG.exception('Unexpected exception caught, bouncing message') + return RESULT_ERROR ellapsed = (time.process_time() - start) * 1000 LOG.info(f'Message delivered in {ellapsed:.2f} ms') @@ -88,7 +91,8 @@ def _main(): _validate_config() keyring_path = conf.get_item('gpg', 'keyhome') - keyring = kcache.KeyRing(keyring_path) + loop = asyncio.get_event_loop() + keyring = kcache.KeyRing(keyring_path, loop) controller = _init_controller(keyring) reloader = _init_reloader(keyring_path, keyring) @@ -99,7 +103,7 @@ def _main(): controller.start() try: - asyncio.run(_sleep()) + loop.run_until_complete(_sleep()) except KeyboardInterrupt: LOG.info("Finishing...") except: diff --git a/lacre/keyring.py b/lacre/keyring.py index 9baa75e..eb158ff 100644 --- a/lacre/keyring.py +++ b/lacre/keyring.py @@ -9,7 +9,7 @@ import lacre.config as conf import logging from os import stat from watchdog.events import FileSystemEventHandler, FileSystemEvent -from asyncio import Semaphore, run +from asyncio import Semaphore, create_task, get_event_loop import copy import GnuPG @@ -73,12 +73,13 @@ class KeyRing: fingerprint=>email maps. """ - def __init__(self, path: str): + def __init__(self, path: str, loop=None): """Initialise the adapter.""" self._path = path self._keys = self._load_and_sanitize() self._sema = Semaphore() self._last_mod = None + self._loop = loop or get_event_loop() def _load_and_sanitize(self): keys = self._load_keyring_from(self._path) @@ -96,7 +97,8 @@ class KeyRing: def load(self): """Load keyring, replacing any previous contents of the cache.""" LOG.debug('Reloading keys...') - run(self._load()) + tsk = create_task(self._load(), 'LoadTask') + self._loop.run_until_complete(tsk) async def _load(self): last_mod = self._read_mod_time()