Concurrency
provide.foundation.concurrency
¶
TODO: Add module docstring.
Classes¶
AsyncLockInfo
¶
Information about a registered async lock.
AsyncLockManager
¶
Async-native centralized lock manager to prevent deadlocks.
Enforces lock ordering and provides timeout mechanisms for async code. All async locks should be acquired through this manager to prevent deadlocks.
Initialize async lock manager.
Source code in provide/foundation/concurrency/async_locks.py
Functions¶
acquire
async
¶
Acquire multiple locks in order to prevent deadlocks.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*lock_names
|
str
|
Names of locks to acquire |
()
|
timeout
|
float
|
Timeout in seconds |
10.0
|
Yields:
| Type | Description |
|---|---|
AsyncGenerator[None, None]
|
None when all locks are acquired |
Raises:
| Type | Description |
|---|---|
TimeoutError
|
If locks cannot be acquired within timeout |
RuntimeError
|
If deadlock would occur or other lock issues |
Source code in provide/foundation/concurrency/async_locks.py
detect_potential_deadlocks
async
¶
Detect potential deadlock situations.
Returns:
| Type | Description |
|---|---|
list[str]
|
List of warnings about potential deadlocks |
Source code in provide/foundation/concurrency/async_locks.py
get_lock
async
¶
Get a registered lock by name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Name of the lock |
required |
Returns:
| Type | Description |
|---|---|
Lock
|
The lock instance |
Raises:
| Type | Description |
|---|---|
KeyError
|
If lock is not registered |
Source code in provide/foundation/concurrency/async_locks.py
get_lock_status
async
¶
Get current status of all locks.
Returns:
| Type | Description |
|---|---|
dict[str, dict[str, Any]]
|
Dictionary with lock status information |
Source code in provide/foundation/concurrency/async_locks.py
register_lock
async
¶
register_lock(
name: str,
order: int,
description: str = "",
lock: Lock | None = None,
) -> asyncio.Lock
Register a lock with the manager.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Unique name for the lock |
required |
order
|
int
|
Order number for deadlock prevention (acquire in ascending order) |
required |
description
|
str
|
Human-readable description |
''
|
lock
|
Lock | None
|
Existing lock to register, or None to create new one |
None
|
Returns:
| Type | Description |
|---|---|
Lock
|
The registered lock |
Raises:
| Type | Description |
|---|---|
ValueError
|
If lock name already exists or order conflicts |
Source code in provide/foundation/concurrency/async_locks.py
LockInfo
¶
Information about a registered lock.
LockManager
¶
Centralized lock manager to prevent deadlocks.
Enforces lock ordering and provides timeout mechanisms. All locks must be acquired through this manager to prevent deadlocks.
Initialize lock manager.
Source code in provide/foundation/concurrency/locks.py
Functions¶
acquire
¶
acquire(
*lock_names: str,
timeout: float = 10.0,
blocking: bool = True
) -> Generator[None, None, None]
Acquire multiple locks in order to prevent deadlocks.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*lock_names
|
str
|
Names of locks to acquire |
()
|
timeout
|
float
|
Timeout in seconds |
10.0
|
blocking
|
bool
|
Whether to block or raise immediately if locks unavailable |
True
|
Yields:
| Type | Description |
|---|---|
None
|
None when all locks are acquired |
Raises:
| Type | Description |
|---|---|
TimeoutError
|
If locks cannot be acquired within timeout |
RuntimeError
|
If deadlock would occur or other lock issues |
Source code in provide/foundation/concurrency/locks.py
detect_potential_deadlocks
¶
Detect potential deadlock situations.
Returns:
| Type | Description |
|---|---|
list[str]
|
List of warnings about potential deadlocks |
Source code in provide/foundation/concurrency/locks.py
get_lock
¶
Get a registered lock by name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Name of the lock |
required |
Returns:
| Type | Description |
|---|---|
RLock
|
The lock instance |
Raises:
| Type | Description |
|---|---|
KeyError
|
If lock is not registered |
Source code in provide/foundation/concurrency/locks.py
get_lock_status
¶
Get current status of all locks.
Returns:
| Type | Description |
|---|---|
dict[str, dict[str, Any]]
|
Dictionary with lock status information |
Source code in provide/foundation/concurrency/locks.py
register_lock
¶
register_lock(
name: str,
order: int,
description: str = "",
lock: RLock | None = None,
) -> threading.RLock
Register a lock with the manager.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Unique name for the lock |
required |
order
|
int
|
Order number for deadlock prevention (acquire in ascending order) |
required |
description
|
str
|
Human-readable description |
''
|
lock
|
RLock | None
|
Existing lock to register, or None to create new one |
None
|
Returns:
| Type | Description |
|---|---|
RLock
|
The registered lock |
Raises:
| Type | Description |
|---|---|
ValueError
|
If lock name already exists or order conflicts |
Source code in provide/foundation/concurrency/locks.py
Functions¶
async_gather
async
¶
Run awaitables concurrently with Foundation tracking.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*awaitables
|
Awaitable[Any]
|
Awaitable objects to run concurrently |
()
|
return_exceptions
|
bool
|
If True, exceptions are returned as results |
False
|
Returns:
| Type | Description |
|---|---|
list[Any]
|
List of results in the same order as input awaitables |
Raises:
| Type | Description |
|---|---|
ValidationError
|
If no awaitables provided |
Example
import asyncio async def fetch_data(n): ... await async_sleep(0.1) ... return n * 2 async def main(): ... results = await async_gather( ... fetch_data(1), fetch_data(2), fetch_data(3) ... ) ... return results asyncio.run(main()) [2, 4, 6]
Source code in provide/foundation/concurrency/core.py
async_run
¶
Run async function with Foundation tracking.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
main
|
Callable[[], Awaitable[Any]]
|
Async function to run |
required |
debug
|
bool
|
Whether to run in debug mode |
False
|
Returns:
| Type | Description |
|---|---|
Any
|
Result of the main function |
Raises:
| Type | Description |
|---|---|
ValidationError
|
If main is not callable |
Example
async def main(): ... await async_sleep(0.1) ... return "hello" result = async_run(main) result 'hello'
Source code in provide/foundation/concurrency/core.py
async_sleep
async
¶
Async sleep with Foundation tracking and cancellation support.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
delay
|
float
|
Number of seconds to sleep |
required |
Raises:
| Type | Description |
|---|---|
ValidationError
|
If delay is negative |
Example
import asyncio async def main(): ... await async_sleep(0.1) asyncio.run(main())
Source code in provide/foundation/concurrency/core.py
async_wait_for
async
¶
Wait for an awaitable with optional timeout.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
awaitable
|
Awaitable[Any]
|
The awaitable to wait for |
required |
timeout
|
float | None
|
Timeout in seconds (None for no timeout) |
required |
Returns:
| Type | Description |
|---|---|
Any
|
Result of the awaitable |
Raises:
| Type | Description |
|---|---|
ValidationError
|
If timeout is negative |
TimeoutError
|
If timeout is exceeded |
Example
import asyncio async def slow_task(): ... await async_sleep(0.2) ... return "done" async def main(): ... try: ... result = await async_wait_for(slow_task(), timeout=0.1) ... except asyncio.TimeoutError: ... result = "timed out" ... return result asyncio.run(main()) 'timed out'
Source code in provide/foundation/concurrency/core.py
get_async_lock_manager
async
¶
Get the global async lock manager instance.
Source code in provide/foundation/concurrency/async_locks.py
get_lock_manager
¶
Get the global lock manager instance.
Source code in provide/foundation/concurrency/locks.py
register_foundation_async_locks
async
¶
Register all foundation async locks with proper ordering.
Lock ordering hierarchy (LOWER numbers = MORE fundamental): - 0-99: Orchestration (coordinator, hub initialization) - 100-199: Early subsystems (logger - needed for debugging) - 200-299: Core infrastructure (config, registry, components) - 300+: Reserved for future subsystems
Source code in provide/foundation/concurrency/async_locks.py
register_foundation_locks
¶
Register all foundation locks with proper ordering.
Lock ordering hierarchy (LOWER numbers = MORE fundamental): - 0-99: Orchestration (coordinator, hub initialization) - 100-199: Early subsystems (logger - needed for debugging) - 200-299: Core infrastructure (config, registry, components) - 300+: Reserved for future subsystems