A flexible low-level tool to make synchronisation primitives in asyncio Python
Project description
fifolock
A flexible low-level tool to make synchronisation primitives in asyncio Python. As the name suggests, locks are granted strictly in the order requested: first-in-first-out; and are not reentrant.
Installation
pip install fifolock
Recipes
Mutex (exclusive) lock
import asyncio
from fifolock import FifoLock
class Mutex(asyncio.Future):
@staticmethod
def is_compatible(holds):
return not holds[Mutex]
lock = FifoLock()
async def access():
async with lock(Mutex):
# access resource
Read/write (shared/exclusive) lock
import asyncio
from fifolock import FifoLock
class Read(asyncio.Future):
@staticmethod
def is_compatible(holds):
return not holds[Write]
class Write(asyncio.Future):
@staticmethod
def is_compatible(holds):
return not holds[Read] and not holds[Write]
lock = FifoLock()
async def read():
async with lock(Read):
# shared access
async def write():
async with lock(Write):
# exclusive access
Semaphore
import asyncio
from fifolock import FifoLock
class SemaphoreBase(asyncio.Future):
@classmethod
def is_compatible(cls, holds):
return holds[cls] < cls.size
lock = FifoLock()
Semaphore = type('Semaphore', (SemaphoreBase, ), {'size': 3})
async def access():
async with lock(Semaphore):
# at most 3 concurrent accesses
Running tests
python setup.py test
Design choices
Each mode of the lock is a subclass of asyncio.Future
. This could be seen as a leak some of the internals of FifoLock
, but it allows for clear client and internal code.
-
Classes are hashable, so each can be a key in the
holds
dictionary passed to theis_compatible
method. This allows the compatibility conditions to be read clearly in the client code, and theholds
dictionary to be mutated clearly internally. -
An instance of it, created inside
FifoLock
, is both the object awaited upon, and stored in a deque with a way of accessing itsis_compatible
method. -
The fact it's a class and not an instance of a class also makes clear it is to store no state, merely configuration.
A downside is that for configurable modes, such as for a semaphore, the client must dynamically create a class: this is not a frequently-used pattern.
The fact that the lock is not reentrant is deliberate: the class of algorithms this is designed for does not require this. This would add unnecessary complexity, and presumably be slower.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for fifolock-0.0.14-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | dc45d7f1eaaafad639759af1615bd103cce247ec54edc421578c63b6826d344c |
|
MD5 | d587554346acbb4eef82a84871d290b0 |
|
BLAKE2b-256 | 39eb6182f13e22c21bab14e7fa9a1460990ea3744cfc7e3725c84aa436e45791 |