Skip to content

Commit 1da91ca

Browse files
committed
Add explanation diagram
1 parent ba9ef77 commit 1da91ca

3 files changed

Lines changed: 18 additions & 19 deletions

File tree

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@
2424
* **Dynamic Controls**: Enable/disable monitoring at runtime, useful for gradual rollout or debugging sessions
2525
* **Exception Raising**: Optionally raise exceptions on high-severity blocking I/O for strict enforcement during development
2626

27+
## How It Works
28+
29+
<p align="center">
30+
<img src="https://raw.githubusercontent.com/feverup/aiocop/master/docs/images/explanation_diagram.png" alt="aiocop architecture diagram">
31+
</p>
32+
33+
aiocop wraps `asyncio.Handle._run` (the method that executes every task in the event loop) and uses Python's `sys.audit` hooks to detect blocking calls. When your code calls a blocking function like `open()`, the audit event is captured along with the full stack trace—letting you know exactly where the problem is.
34+
2735
## Why aiocop?
2836

2937
aiocop was built to solve specific production constraints that existing approaches didn't quite fit.

docs/guide.md

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,25 +24,16 @@ aiocop uses three mechanisms to detect blocking I/O:
2424

2525
3. **Event Loop Patching** (`detect_slow_tasks`): Patches `asyncio.Handle._run` to measure task execution time and invoke callbacks when blocking is detected.
2626

27-
```
28-
┌─────────────────────────────────────────────────────────────┐
29-
│ Event Loop │
30-
│ ┌─────────────────────────────────────────────────────┐ │
31-
│ │ Handle._run() │ │
32-
│ │ ┌───────────────────────────────────────────────┐ │ │
33-
│ │ │ Your Async Task │ │ │
34-
│ │ │ │ │ │
35-
│ │ │ time.sleep(0.1) ──► Audit Event Emitted │ │ │
36-
│ │ │ │ │ │ │ │
37-
│ │ │ ▼ ▼ │ │ │
38-
│ │ │ [Blocking!] [Captured by Hook] │ │ │
39-
│ │ └───────────────────────────────────────────────┘ │ │
40-
│ │ │ │ │
41-
│ │ ▼ │ │
42-
│ │ Callback Invoked with Event │ │
43-
│ └─────────────────────────────────────────────────────┘ │
44-
└─────────────────────────────────────────────────────────────┘
45-
```
27+
![aiocop architecture diagram](images/explanation_diagram.png)
28+
29+
The diagram above shows the complete flow:
30+
31+
1. The **Event Loop** schedules a task via `Handle._run`
32+
2. **aiocop's wrapper** starts a timer and creates an events list
33+
3. Your **task code** executes
34+
4. When a blocking function (like `open()`) is called, the **Python VM** (for native functions) or **aiocop's wrapper** (for patched functions) emits a `sys.audit` event
35+
5. The **audit hook** captures the event and stack trace, appending it to the events list
36+
6. After the task completes, aiocop calculates severity and invokes callbacks with the full `SlowTaskEvent`
4637

4738
## Setup Functions
4839

976 KB
Loading

0 commit comments

Comments
 (0)