Registry / database / aiologic

aiologic

JSON →
library0.16.0pypypi✓ verified 52d ago

AioLogic is a GIL-powered locking library for Python (current version 0.16.0) that provides synchronization primitives which are both async-aware and thread-aware. It addresses common challenges in concurrent programming by enabling seamless interaction between asynchronous code (within and across multiple threads/event loops) and synchronous code, and between different synchronous threads, offering a unified API for various concurrency models. The library is actively maintained with a focus on performance and broad compatibility.

databasehttp-networkingdata
pip install aiologic
Install & Compatibility
Where this runs
tested against v0.16.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.920 runs
installs and imports cleanly · install 0.0s · import 0.311s · 20.3MB
glibc
py 3.103.920 runs
installs and imports cleanly · install 2.1s · import 0.280s · 21MB
18MB installed
● package 18MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

Lock
from aiologic import Lock
Condition
from aiologic import Condition
synchronized
from aiologic import synchronized

This example demonstrates how `aiologic.Lock` can synchronize access to a shared resource across multiple asyncio event loops running in different OS threads. Standard `asyncio.Lock` would raise a RuntimeError, and `threading.Lock` would cause a deadlock in such a scenario.

import asyncio from threading import Thread from aiologic import Lock lock = Lock() async def func(i: int, j: int) -> None: print(f"thread={i} task={j} start") async with lock: await asyncio.sleep(0.1) # Simulate some async work print(f"thread={i} task={j} end") async def main(i: int) -> None: await asyncio.gather(func(i, 0), func(i, 1)) # Run two asyncio event loops in separate threads, sharing one aiologic.Lock thread0 = Thread(target=asyncio.run, args=[main(0)]) thread1 = Thread(target=asyncio.run, args=[main(1)]) thread0.start() thread1.start() thread0.join() thread1.join() print("All threads and tasks completed.")
Debug
Known issues
breakingVersion 0.13.0 introduced significant internal source code refactoring and type annotations via stubs. Objects pickled with previous versions of `aiologic` might become unusable.
fix
Repickle any `aiologic` objects after upgrading to 0.13.0 or newer. Review code for potential type annotation ambiguities if using specific IDEs or strict type checkers.
affects: 0.13.0 and older
gotchaUnlike `asyncio.Lock` or `threading.Lock`, `aiologic.Lock` is designed to work across different asyncio event loops running in separate threads, and to synchronize between async and sync code. Directly using `asyncio.Lock` in such cross-thread/cross-event-loop scenarios will result in a `RuntimeError`, and `threading.Lock` will lead to deadlocks by blocking event loops.
fix
Always use `aiologic.Lock` (or other `aiologic` primitives) when synchronization is required between different event loops, between async and sync code, or in complex multi-threaded async applications.
affects: All versions
deprecatedThe `aiologic.lowlevel.shield()` function was replaced by `aiologic.lowlevel.repeat_if_cancelled()` due to limitations with `anyio.CancelScope` not reliably shielding calls from external cancellations.
fix
Migrate usage from `aiologic.lowlevel.shield()` to `aiologic.lowlevel.repeat_if_cancelled()` for robust cancellation handling.
affects: Prior to 0.10.0
gotchaIn version 0.14.0, the mechanism for detecting support for underlying concurrency libraries (like `eventlet`, `gevent`, `asyncio`, `trio`, `curio`, `anyio`) changed from post-first-use to post-import hooks. This means library support is activated when the corresponding library is imported, which might alter behavior in interactive or dynamically loaded scenarios compared to previous versions.
fix
Be aware of the new library detection timing. If experiencing unexpected behavior related to concurrency library integration, ensure all relevant libraries are imported before `aiologic` primitives are used.
affects: 0.14.0 and newer
Errors
Common errors & fixes
RuntimeError: Cannot run asyncio.run() in a running event loop
Attempting to use `asyncio.Lock` or other `asyncio` primitives to synchronize across multiple `asyncio.run()` calls invoked from different threads, or between different event loops.
fix
Use `aiologic.Lock` instead. `aiologic` primitives are designed to be both async-aware and thread-aware, allowing synchronization across different event loops in separate threads.
Application deadlocks or unresponsive tasks when trying to acquire a lock in a mixed async/sync environment.
Using `threading.Lock` in an asynchronous context or to synchronize tasks running in different `asyncio` event loops. `threading.Lock` is blocking and not aware of event loop scheduling, leading to deadlocks.
fix
Replace `threading.Lock` with `aiologic.Lock`. `aiologic.Lock` provides a non-blocking, async-aware, and thread-safe mechanism for synchronization.
TypeError: object <lock_type> is not awaitable
Attempting to `await` a synchronous lock primitive (e.g., from `threading` module) or using an asynchronous primitive (e.g., from `asyncio`) in a synchronous context without proper handling.
fix
Ensure you are using the correct `aiologic` primitive (`aiologic.Lock`, `aiologic.Condition`, etc.) for your context. `aiologic` primitives expose both synchronous (e.g., `acquire()`, `release()`) and asynchronous (e.g., `async_acquire()`, `async_release()`, or `async with`) interfaces that adapt to the environment.
Upgrade
Version history
0.16.0latest on PyPI
Audit
Dependencies
pythonrequiredRequires Python 3.8 or higher.
Agent activity
113 hits · last 30 days
node
18
claudebot
4
petalbot
3
ahrefsbot
3
Amazon
1
applebot
1
amazonbot
1
seranking-bot
1
Resources