fix: isolate citation registries per pipeline - #487
Conversation
|
@xhd0728 This focused LightResearch concurrency fix is ready for review. It scopes citation registries by pipeline-run ID, carries that ID through generated tool metadata, and releases the registry on completion; the regression interleaves two runs and verifies independent counters. The focused pytest, pipeline build, MCP metadata smoke, and targeted Ruff checks pass. Since you maintain and review |
|
Thanks for the fix! The registry isolation works in our interleaved-request tests, but further testing found two issues:
Could you move cleanup into a guaranteed lifecycle/finally path that preserves the generated result and handles failures and cancellation? Please also add regression tests for these cases before merging. |
|
Chiming in from #408 (the thread-local attempt this PR supersedes) — the two issues @xhd0728 found both trace to the same design choice: the registry state lives in a class-level global ( Two ways to remove the global-lifecycle problem entirely: Option A — carry the state in the pipeline context (no global at all). The registry state is just Option B — keep the registry-id design, replace the trailing step with allocation-time GC. Add a Either way, the regression tests that would pin this down: (1) interleaved runs keep independent counters (already present), (2) a pipeline that raises after Happy to test either approach against the interleaved MCP-client scenario from the maintainer testing on this thread, or to send a patch if useful — we have the failing repro from #394 wired up locally. |
Summary
Root cause
init_citation_registry()reset a class-level dictionary shared by every request. Starting a second pipeline therefore erased the first pipeline's in-progress citation mappings.Validation
pytest -p no:cacheprovider tests/test_citation_registry.py -qultrarag build examples/demos/LightResearch.yamlruff check --select I,F,E9 tests/test_citation_registry.pyruff check --select I servers/custom/src/custom.pyFixes #394