Skip to content

Commit aae2cee

Browse files
committed
docs: describe the one-event-loop-per-instance rule for async resilience middleware
1 parent b66067b commit aae2cee

1 file changed

Lines changed: 26 additions & 0 deletions

File tree

‎docs/resilience.md‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,32 @@ async def main() -> None:
363363

364364
Your own middleware that sets something per call, like the request-ID middleware in [Middleware](middleware.md), also belongs before `AsyncRetry`, so every attempt of a call shares one ID.
365365

366+
## One event loop per instance
367+
368+
`AsyncBulkhead`, `AsyncCircuitBreaker` and `AsyncKeyedCircuitBreaker` are bound to the event loop they first run on. Using the same instance from another loop raises `RuntimeError`, and so does a later `asyncio.run()` in the same thread, because each `asyncio.run()` starts a new loop. `httpx2.AsyncClient` can't be reused across `asyncio.run()` calls either. Create the async resilience middleware, and the `AsyncClient` holding it, once per event loop, for example inside the coroutine you pass to `asyncio.run()`:
369+
370+
```python
371+
import asyncio
372+
373+
from httpware import AsyncClient
374+
from httpware.middleware.resilience import AsyncCircuitBreaker, AsyncRetry
375+
376+
377+
async def main() -> None:
378+
async with AsyncClient(
379+
base_url="https://api.example.com",
380+
middleware=[AsyncCircuitBreaker(), AsyncRetry()],
381+
) as client:
382+
await client.get("/users/1")
383+
384+
385+
asyncio.run(main())
386+
```
387+
388+
The usual way to hit the error is in tests: pytest-asyncio gives each test function its own loop by default, so an instance created at module level or in a session-scoped fixture fails in the second test that uses it. Create it in a function-scoped fixture or in the test.
389+
390+
To share a cap or a circuit across threads, use the sync classes with `Client`.
391+
366392
## Sync Retry and Bulkhead
367393

368394
Use these with the sync `Client`.

0 commit comments

Comments
 (0)