deerflow2/backend/tests/blocking_io
AochenShen99 9f3be2a9fa
fix(agents): offload UploadsMiddleware uploads scan off the event loop (#3311)
UploadsMiddleware defines only the sync `before_agent` hook. LangChain wires a
sync-only hook as `RunnableCallable(before_agent, None)`, and LangGraph's
`ainvoke` runs it directly on the event loop when `afunc is None` — so the
per-message uploads-directory scan (`exists`/`iterdir`/`stat` plus reading
sibling `.md` outlines) blocks the asyncio event loop on every message that has
an uploads directory.

Add `abefore_agent` that offloads the scan to a worker thread via
`run_in_executor`; it copies the current context, preserving the `user_id`
contextvar read by `get_effective_user_id()`.

Add a runtime anchor under `tests/blocking_io/` that drives the real
`create_agent` graph via `ainvoke` under the strict Blockbuster gate, so a
regression back onto the event loop fails CI. Update blocking-IO docs.
2026-05-30 21:46:35 +08:00
..
__init__.py feat(tests): add Blockbuster runtime gate for event-loop blocking IO (#3229) 2026-05-26 23:03:49 +08:00
conftest.py feat(tests): add Blockbuster runtime gate for event-loop blocking IO (#3229) 2026-05-26 23:03:49 +08:00
test_gate_smoke.py feat(tests): add Blockbuster runtime gate for event-loop blocking IO (#3229) 2026-05-26 23:03:49 +08:00
test_jsonl_run_event_store.py test(runtime): add Blockbuster runtime anchor for JsonlRunEventStore async IO (#3313) 2026-05-29 23:02:41 +08:00
test_skills_load.py feat(tests): add Blockbuster runtime gate for event-loop blocking IO (#3229) 2026-05-26 23:03:49 +08:00
test_sqlite_lifespan.py feat(tests): add Blockbuster runtime gate for event-loop blocking IO (#3229) 2026-05-26 23:03:49 +08:00
test_uploads_middleware.py fix(agents): offload UploadsMiddleware uploads scan off the event loop (#3311) 2026-05-30 21:46:35 +08:00