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
This commit is contained in:
Piotr F. Mieszkowski 2022-10-29 16:09:24 +02:00
parent 9f1c4db49d
commit 91969dbfbb
2 changed files with 11 additions and 5 deletions

View File

@ -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:

View File

@ -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()