Fix: Allow running in environments with existing event loop#222
Fix: Allow running in environments with existing event loop#222zhenliemao wants to merge 7 commits into
Conversation
Summary: This fix allows SkillSpector to run in environments that already have a running event loop, preventing RuntimeError when asyncio.run() is called from within an existing loop. Problem: When running SkillSpector in environments like: - Jupyter Notebooks - LangGraph Studio - FastAPI applications - Any programmatic usage within async code The call to asyncio.run() throws a RuntimeError: This event loop is already running and falls back to unfiltered static findings, silently disabling LLM analysis. The previous approach of detecting this state via error message substring matching is fragile and locale-dependent. Solution: 1. Add utility function in that properly detects running loops using 2. When no running loop exists, fall back to directly 3. When a loop is already running, offload execution to a separate thread with its own event loop via 4. Replace all calls across all analyzer nodes with the new helper 5. Remove unused asyncio imports from analyzer files Test: Add comprehensive unit tests for run_async covering: - Normal execution without existing running loop - Nested execution inside an already running loop - Exception propagation from async coroutines - Correct handling of async functions with await calls Signed-off-by: zhenliemao <494822673@qq.com>
Signed-off-by: zhenliemao <494822673@qq.com>
rng1995
left a comment
There was a problem hiding this comment.
The helper is a reasonable approach, but two blockers remain: the behavior that prevents nested asyncio.run failures has no test coverage, and current head conflicts with main in src/skillspector/llm_utils.py. Please rebase and resolve the conflict, then add focused running-loop tests before merge.
| except RuntimeError: | ||
| return asyncio.run(coroutine) | ||
|
|
||
| with concurrent.futures.ThreadPoolExecutor(max_workers=1) as executor: |
There was a problem hiding this comment.
This is the core behavior the PR exists to change, but no test exercises either branch. Add regressions that call run_async outside an event loop and from within a running loop, and assert both successful results and exception propagation.
Signed-off-by: zhenliemao <494822673@qq.com>
rng1995
left a comment
There was a problem hiding this comment.
[Automated SkillSpector Review]
Re-review: still requesting changes. The prior behavioral-test gap is resolved and the merge conflict is gone: the new tests cover both event-loop branches and exception propagation. Current head nevertheless fails every Python CI job because the changed import block fails ruff I001; the merge commit also fails DCO. Run ruff check/format, sign off all PR commits, and restore green checks.
| import concurrent.futures | ||
| from collections.abc import Coroutine | ||
| from typing import Any | ||
| import json |
There was a problem hiding this comment.
Blocking: this import block is unsorted (json appears after typing imports), and all Python CI jobs stop at ruff I001 here. Organize the imports and run both ruff check and ruff format --check over src/ and tests/; the newly added test class also needs formatter cleanup.
Signed-off-by: zhenliemao <494822673@qq.com>
d4bc2bc to
7eefd67
Compare
Signed-off-by: zhenliemao <494822673@qq.com>
Signed-off-by: zhenliemao <494822673@qq.com>
Signed-off-by: zhenliemao <494822673@qq.com>
916cc94 to
24cfc13
Compare
|
i have pushed new commits that resolved the DCO problems, ruff check and conflict |
Summary:
This fix allows SkillSpector to run in environments that already have a running event loop, preventing RuntimeError when asyncio.run() is called from within an existing loop.
Problem:
When running SkillSpector in environments like:
Solution:
Test:
Add comprehensive unit tests for run_async covering:
Fixes [BUG] RuntimeError: asyncio.run() called from within an already running event loop #108