{"id":6969,"library":"aiologic","title":"AioLogic","description":"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.","status":"active","version":"0.16.0","language":"en","source_language":"en","source_url":"https://github.com/x42005e1f/aiologic","tags":["async","asyncio","threading","concurrency","locking","semaphore","queue","multithreading","event-loop"],"install":[{"cmd":"pip install aiologic","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Requires Python 3.8 or higher.","package":"python","optional":false}],"imports":[{"symbol":"Lock","correct":"from aiologic import Lock"},{"symbol":"Condition","correct":"from aiologic import Condition"},{"symbol":"synchronized","correct":"from aiologic import synchronized"}],"quickstart":{"code":"import asyncio\nfrom threading import Thread\nfrom aiologic import Lock\n\nlock = Lock()\n\nasync def func(i: int, j: int) -> None:\n    print(f\"thread={i} task={j} start\")\n    async with lock:\n        await asyncio.sleep(0.1) # Simulate some async work\n        print(f\"thread={i} task={j} end\")\n\nasync def main(i: int) -> None:\n    await asyncio.gather(func(i, 0), func(i, 1))\n\n# Run two asyncio event loops in separate threads, sharing one aiologic.Lock\nthread0 = Thread(target=asyncio.run, args=[main(0)])\nthread1 = Thread(target=asyncio.run, args=[main(1)])\n\nthread0.start()\nthread1.start()\n\nthread0.join()\nthread1.join()\nprint(\"All threads and tasks completed.\")","lang":"python","description":"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."},"warnings":[{"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.","message":"Version 0.13.0 introduced significant internal source code refactoring and type annotations via stubs. Objects pickled with previous versions of `aiologic` might become unusable.","severity":"breaking","affected_versions":"0.13.0 and older"},{"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.","message":"Unlike `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.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Migrate usage from `aiologic.lowlevel.shield()` to `aiologic.lowlevel.repeat_if_cancelled()` for robust cancellation handling.","message":"The `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.","severity":"deprecated","affected_versions":"Prior to 0.10.0"},{"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.","message":"In 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.","severity":"gotcha","affected_versions":"0.14.0 and newer"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"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.","cause":"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.","error":"RuntimeError: Cannot run asyncio.run() in a running event loop"},{"fix":"Replace `threading.Lock` with `aiologic.Lock`. `aiologic.Lock` provides a non-blocking, async-aware, and thread-safe mechanism for synchronization.","cause":"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.","error":"Application deadlocks or unresponsive tasks when trying to acquire a lock in a mixed async/sync environment."},{"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.","cause":"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.","error":"TypeError: object <lock_type> is not awaitable"}]}