- New feature: CPU stack sampling — a watchdog daemon thread samples the loop thread's stack during CPU-bound slices, attaching aggregated stacks with counts to
SlowTaskEvent.cpu_stack_samples, socpu_blockingevents carry attribution like IO events do - On by default:
detect_slow_tasks()starts it automatically (cpu_sampling=Falseto opt out);start_cpu_sampling()called beforehand customizes it - Derived defaults: arming delay follows half the slow-task threshold; idle wake-up follows
min(50ms, max(arm, interval))with a 1ms sleep floor, so no configuration can busy-loop the watchdog - Samples the thread that published the slice — event loops running outside the main thread are attributed correctly
- Fork-safe: forked children (e.g. gunicorn
--preloadworkers) restart the watchdog viaos.register_at_fork - aiocop's own frames are excluded from samples via a package-path prefix match
- Fix
time.sleepbeing double-counted on Python 3.13+, which emits a native audit event for it (#11, #12) - Make
patch_audit_functions()andstart_blocking_io_detection()idempotent — repeat calls now warn and no-op instead of silently double-counting events (#9, #10)
- Capture context both before and after callback execution, merging non-None post values over pre values to handle spans set lazily
- Capture context provider before call
- First stable release
- Add classifiers
- Small fixes
- First release on PyPI.