Skip to content

fix: replace deprecated asyncio.get_event_loop() with get_running_loop()#12124

Open
gambletan wants to merge 1 commit intolangflow-ai:mainfrom
gambletan:fix/asyncio-get-running-loop
Open

fix: replace deprecated asyncio.get_event_loop() with get_running_loop()#12124
gambletan wants to merge 1 commit intolangflow-ai:mainfrom
gambletan:fix/asyncio-get-running-loop

Conversation

@gambletan
Copy link

@gambletan gambletan commented Mar 10, 2026

Summary

  • Replace all asyncio.get_event_loop() calls with asyncio.get_running_loop() in two files:
    • src/backend/base/langflow/main.py (30 occurrences in the async lifespan context manager)
    • src/lfx/src/lfx/base/mcp/util.py (4 occurrences in async methods of MCPSessionManager)

Motivation

asyncio.get_event_loop() has been deprecated since Python 3.10 and emits a DeprecationWarning when called without a running event loop. Since Langflow requires Python >= 3.10, and all call sites in this PR are inside async functions (where a running loop is guaranteed), asyncio.get_running_loop() is the correct replacement.

get_running_loop() is also safer: it raises a RuntimeError if no loop is running, rather than silently creating a new one—making bugs easier to catch.

Test plan

  • All replaced call sites are inside async def functions, so get_running_loop() will always find the running loop
  • No behavioral change: both APIs return the same loop object when called from within an async context
  • Existing tests should pass without modification

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved internal timing accuracy in asynchronous operations.

@github-actions github-actions bot added the community Pull Request from an external contributor label Mar 10, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 10, 2026

Walkthrough

Two files were updated to replace asyncio.get_event_loop().time() calls with asyncio.get_running_loop().time() for time measurements. The changes affect initialization logging in the main module and idle cleanup/session tracking in the MCP utility module. No functional behavior or control flow is altered.

Changes

Cohort / File(s) Summary
Backend initialization timing
src/backend/base/langflow/main.py
Updated all asyncio timing calls from get_event_loop().time() to get_running_loop().time() for start_time, intermediate current_time measurements, and total_time calculations in lifespan initialization logs.
MCP session management timing
src/lfx/src/lfx/base/mcp/util.py
Updated asyncio timing calls from get_event_loop().time() to get_running_loop().time() for idle cleanup timestamps and per-session last_used tracking.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Test Coverage For New Implementations ❌ Error PR modifies asyncio calls in two files but includes no new or updated test files to verify the changes. Add test files to validate the asyncio changes in both modified modules, particularly for lifespan initialization and MCPSessionManager async operations.
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Test File Naming And Structure ⚠️ Warning Test files follow proper pytest patterns with comprehensive coverage, but deprecated asyncio.get_event_loop().time() calls remain in test_mcp_memory_leak.py and main.py lifespan changes lack dedicated integration tests. Replace deprecated asyncio.get_event_loop().time() calls in test_mcp_memory_leak.py with asyncio.get_running_loop().time() and add integration tests for main.py lifespan changes.
Test Quality And Coverage ❓ Inconclusive PR modifies critical async code replacing asyncio.get_event_loop() with get_running_loop(), but no test files exercising these code paths were found in the repository. Verify if tests exist for lifespan initialization and MCPSessionManager methods; check CI/CD logs to confirm existing tests pass; consider adding integration tests for async context manager timing measurements.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: replacing deprecated asyncio.get_event_loop() with get_running_loop() across two files.
Excessive Mock Usage Warning ✅ Passed The PR exclusively modifies source files without changing any test files, making the mock usage assessment not applicable.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Mar 10, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/backend/base/langflow/main.py (1)

192-194: Reset the timer before the unconditional superuser init.

Line 194 is still measuring against the previous current_time. That makes this startup metric inaccurate: it includes the prior block when AUTO_LOGIN is enabled, and can include unrelated earlier work when it is disabled.

⏱️ Proposed fix
             await logger.adebug("Initializing super user")
+            current_time = asyncio.get_running_loop().time()
             await initialize_auto_login_default_superuser()
             await logger.adebug(f"Super user initialized in {asyncio.get_running_loop().time() - current_time:.2f}s")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/backend/base/langflow/main.py` around lines 192 - 194, The elapsed-time
log for the unconditional superuser init is using an earlier current_time, so
before calling logger.adebug("Initializing super user") and
initialize_auto_login_default_superuser() reset the timer by assigning
current_time = asyncio.get_running_loop().time(); then use that current_time in
the later logger.adebug(f"Super user initialized in
{asyncio.get_running_loop().time() - current_time:.2f}s") to measure only the
superuser initialization; the relevant symbols to update are logger.adebug and
initialize_auto_login_default_superuser and the
asyncio.get_running_loop().time() call.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/backend/base/langflow/main.py`:
- Around line 192-194: The elapsed-time log for the unconditional superuser init
is using an earlier current_time, so before calling logger.adebug("Initializing
super user") and initialize_auto_login_default_superuser() reset the timer by
assigning current_time = asyncio.get_running_loop().time(); then use that
current_time in the later logger.adebug(f"Super user initialized in
{asyncio.get_running_loop().time() - current_time:.2f}s") to measure only the
superuser initialization; the relevant symbols to update are logger.adebug and
initialize_auto_login_default_superuser and the
asyncio.get_running_loop().time() call.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 794d8688-b7c7-414c-bc68-794ad6556cb3

📥 Commits

Reviewing files that changed from the base of the PR and between 351b943 and 9bef75c.

📒 Files selected for processing (2)
  • src/backend/base/langflow/main.py
  • src/lfx/src/lfx/base/mcp/util.py

@gambletan
Copy link
Author

Good catch on the stale current_time — I'll add current_time = asyncio.get_running_loop().time() before the superuser init call. Will also update test_mcp_memory_leak.py to use get_running_loop() and add test coverage for the asyncio changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working community Pull Request from an external contributor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant