cadrumo.core.async_cleanup module

Cancellation-complete awaiting for owned asynchronous cleanup.

Resource owners use await_cancellation_complete() when losing the local task handle would make a second cancellation leak an external process or session. The cleanup runs in one retained task; every caller cancellation is deferred until that task reaches a terminal state.

class AsyncCloseable(*args, **kwargs)[source]

Bases: Protocol

Structural asynchronous resource owner.

async close()[source]

Release the owned resource.

Return type:

None

exception AsyncResourceCleanupError(resources, failures, *, retry_task_name, close_attempts)[source]

Bases: CoreError

Retain asynchronous resource owners whose close attempts failed.

Parameters:
Return type:

None

async retry_cleanup()[source]

Retry only the resource owners whose prior close failed.

Return type:

None

merged_with(later)[source]

Combine nested cleanup failures without losing either owner.

Return type:

AsyncResourceCleanupError

Parameters:

later (AsyncResourceCleanupError)

code
async await_cancellation_complete(awaitable, *, task_name, cancellation=None)[source]

Finish awaitable before preserving and re-raising cancellation.

Repeated calls to asyncio.Task.cancel() are absorbed while the retained cleanup task is pending. If cleanup itself fails while a caller cancellation is pending, that failure is retained on the cancellation as cleanup_error and the cancellation remains the primary exception.

Return type:

TypeVar(T)

Parameters:
  • awaitable (Awaitable)

  • task_name (str)

  • cancellation (CancelledError | None)

async close_async_resources(*resources, task_name, cancellation=None, primary_error=<cadrumo.core.async_cleanup._AutoPrimaryException object>, close_attempts=1)[source]

Close every resource without replacing an exception already unwinding.

When called from an async finally block, sys.exception() exposes the body exception across this coroutine boundary. Cleanup still reaches a terminal state, and any owner-retaining cleanup error is attached to that primary exception instead of replacing it.

Return type:

None

Parameters:
  • resources (AsyncCloseable | None)

  • task_name (str)

  • cancellation (CancelledError | None)

  • primary_error (BaseException | _AutoPrimaryException | None)

  • close_attempts (int)