From e39632e686963c49241abf0f12eab96265683d7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20S=C3=A1nchez-Gallego?= Date: Sat, 18 Nov 2023 13:53:38 -0800 Subject: [PATCH] Improve locking mechanism --- python/lvmecp/modbus.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/python/lvmecp/modbus.py b/python/lvmecp/modbus.py index 5793764..c75ed07 100644 --- a/python/lvmecp/modbus.py +++ b/python/lvmecp/modbus.py @@ -257,13 +257,10 @@ async def disconnect(self): async def __aenter__(self): """Initialises the connection to the server.""" - # Acquire the lock, but also don't allow it to block for too long. try: await asyncio.wait_for(self.lock.acquire(), 10) except asyncio.TimeoutError: - log.warning("Timed out waiting for lock to be released. Forcing release.") - self.lock.release() - await self.lock.acquire() + raise RuntimeError("Timed out waiting for lock to be released.") try: await self.connect() @@ -273,6 +270,11 @@ async def __aenter__(self): raise + # Schedule a task to release the lock after 5 seconds. This is a safeguard + # in case something fails and the connection is never closed and the lock + # not released. + asyncio.create_task(self.unlock_on_timeout()) + async def __aexit__(self, exc_type, exc, tb): """Closes the connection to the server.""" @@ -282,6 +284,13 @@ async def __aexit__(self, exc_type, exc, tb): if self.lock.locked(): self.lock.release() + async def unlock_on_timeout(self): + """Removes the lock after an amount of time.""" + + await asyncio.sleep(10) + if self.lock.locked(): + self.lock.release() + async def get_all(self): """Returns a dictionary with all the registers."""