Skip to main content

A flexible low-level tool to make synchronisation primitives in asyncio Python

Project description

fifolock CircleCI Maintainability Test Coverage

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.


pip install fifolock


Mutex (exclusive) lock

import asyncio
from fifolock import FifoLock

class Mutex(asyncio.Future):
    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):
    def is_compatible(holds):
        return not holds[Write]

class Write(asyncio.Future):
    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


import asyncio
from fifolock import FifoLock

class SemaphoreBase(asyncio.Future):
    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 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 the is_compatible method. This allows the compatibility conditions to be read clearly in the client code, and the holds 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 its is_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.

Project details

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for fifolock, version 0.0.5
Filename, size File type Python version Upload date Hashes
Filename, size fifolock-0.0.5-py3-none-any.whl (3.5 kB) File type Wheel Python version py3 Upload date Hashes View
Filename, size fifolock-0.0.5.tar.gz (2.6 kB) File type Source Python version None Upload date Hashes View

Supported by

Pingdom Pingdom Monitoring Google Google Object Storage and Download Analytics Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page