Skip to content

feat(lfx): configure component load worker count - #15770

Open
yu1128-L wants to merge 1 commit into
langflow-ai:release-1.13.0from
yu1128-L:fix/configurable-component-load-workers-11354
Open

yu1128-L wants to merge 1 commit into
langflow-ai:release-1.13.0from
yu1128-L:fix/configurable-component-load-workers-11354

Conversation

@yu1128-L

@yu1128-L yu1128-L commented Oct 15, 2026 •

Copy link
Copy Markdown

Fixes #11354

Why

In containers with CPU limits, asyncio.to_thread() sizes its default thread
pool from os.cpu_count(), which can reflect the host node instead of the
container limit. Component loading can create substantially more threads than
the allocated CPU budget and make startup slow.

What changed

  • Add component_load_max_workers to the component settings.
  • Read the value from LANGFLOW_COMPONENT_LOAD_MAX_WORKERS.
  • Keep the existing asyncio.to_thread() behavior when the setting is unset.
  • Use a bounded ThreadPoolExecutor when a positive worker count is
    configured.
  • Reject zero and negative values through settings validation.
  • Document the setting in .env.example and add unit coverage.

Validation

  • Focused pytest: 96 passed, 7 warnings in 98.13s
  • ruff check src/lfx/src/lfx/interface/components.py src/lfx/src/lfx/services/settings/groups/components.py src/lfx/tests/unit/test_component_index.py src/lfx/tests/unit/services/settings/test_settings_composition.py: passed
  • ruff format --check on the same paths: passed

AI assistance

Codex generated the implementation and tests from issue #11354. I reviewed the
full diff and ran the validation above.

Summary by CodeRabbit

  • New Features
    • Component loading can use an optional positive worker limit, configurable through LANGFLOW_COMPONENT_LOAD_MAX_WORKERS. When unset, the default thread pool remains in use.

@github-actions github-actions Bot added the enhancement New feature or request label Oct 15, 2026
@coderabbitai

coderabbitai Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: langflow-ai/langflow/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 2cfd2c1a-0ce2-4cc5-a7a9-74c8b8ad8a86
📥 Commits

Reviewing files that changed from the base of the PR and between 313f077 and 3b642f7.

📒 Files selected for processing: 2
  • src/lfx/tests/unit/services/settings/test_settings_composition.py
  • src/lfx/tests/unit/test_component_index.py

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

Walkthrough

Adds an optional setting to cap worker threads used during dynamic component loading. The setting defaults to None, which retains asyncio.to_thread behavior. When configured, loading paths use a dedicated ThreadPoolExecutor with the specified worker limit.

Changes

Component loading worker limit

Layer / File(s) Summary
Worker limit setting and validation
.env.example, src/lfx/src/lfx/services/settings/groups/components.py, src/lfx/tests/unit/services/settings/test_settings_composition.py
Adds component_load_max_workers, defaulting to None and requiring configured values to be greater than zero. Documents the environment variable and tests its default, binding, and validation.
Bounded dynamic loading and mode wiring
src/lfx/src/lfx/interface/components.py, src/lfx/tests/unit/test_component_index.py
Passes the setting through full-dev, selective-dev, and production loading paths. Dynamic imports use a named ThreadPoolExecutor when a limit is set. Tests cover the default asyncio.to_thread path, the worker cap, and settings forwarding.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Feature · Severity of issue fixed: Medium

Sequence Diagram(s)

sequenceDiagram
  participant SettingsService
  participant import_langflow_components
  participant _load_components_dynamically
  participant ThreadPoolExecutor
  participant ComponentModules
  SettingsService->>import_langflow_components: provide component_load_max_workers
  import_langflow_components->>_load_components_dynamically: pass worker limit
  alt worker limit is configured
    _load_components_dynamically->>ThreadPoolExecutor: submit module imports with worker cap
    ThreadPoolExecutor->>ComponentModules: import modules
  else worker limit is unset
    _load_components_dynamically->>ComponentModules: import modules via asyncio.to_thread
  end
Loading

Suggested reviewers: erichare

Merge Risk: ⚪ Minimal · up to 3b642

No demonstrated issue currently prevents merging after normal checks.

Pre-merge checks: Passed 9
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: configuring the component-loading worker count.
Linked Issues check Passed Issue [#11354] requires a configurable worker count for initial component loading and current behavior when the value is unset. ComponentsSettings adds component_load_max_workers with gt=0. Sett…
Out of Scope Changes check Passed The changes stay within issue [#11354]. They modify component-loading concurrency, component settings, environment documentation, and related automated tests. The changes do not apply the setting to u…
Docstring Coverage Passed Docstring coverage is 94.12% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 17 functions across 4 files.
Test Coverage For New Implementations Passed The PR includes matching backend tests with the project naming convention. test_settings_composition.py covers the new setting field, default, environment binding, and rejection of zero or negative …
Test Quality And Coverage Passed Tests cover the new behavior with pytest async patterns. Settings tests verify the default, environment binding, and rejection of zero and negative values. Dynamic-loader tests verify the unset path u…
Test File Naming And Structure Passed The changed backend test files use the required test_*.py pattern and reside under src/lfx/tests/unit. They use pytest classes, fixtures, async markers, parametrization, mocks, and context-managed…
Excessive Mock Usage Warning Passed No excessive mock usage is introduced. The settings tests construct real Settings objects and use only environment patching. The concurrency test uses a real ThreadPoolExecutor, real worker blocki…
Full details: Linked Issues check

Explanation

Issue [#11354] requires a configurable worker count for initial component loading and current behavior when the value is unset. ComponentsSettings adds component_load_max_workers with gt=0. Settings tests verify the LANGFLOW_COMPONENT_LOAD_MAX_WORKERS environment variable, the default None, and rejection of 0 and -1. Component loading uses asyncio.to_thread when the value is unset and a bounded ThreadPoolExecutor when it is set. The worker limit propagates through full development loading, selective development loading, and production fallback loading. .env.example documents the setting.

Full details: Out of Scope Changes check

Explanation

The changes stay within issue [#11354]. They modify component-loading concurrency, component settings, environment documentation, and related automated tests. The changes do not apply the setting to unrelated asyncio.to_thread() operations.

Full details: Test Coverage For New Implementations

Explanation

The PR includes matching backend tests with the project naming convention. test_settings_composition.py covers the new setting field, default, environment binding, and rejection of zero or negative values. test_component_index.py covers the unset asyncio.to_thread path, the bounded ThreadPoolExecutor path, and configured worker-limit forwarding through development and production loading. These unit tests exercise the new behavior through the public component import path; no separate integration harness is needed for this isolated settings and loader-concurrency change.

Full details: Test Quality And Coverage

Explanation

Tests cover the new behavior with pytest async patterns. Settings tests verify the default, environment binding, and rejection of zero and negative values. Dynamic-loader tests verify the unset path uses asyncio.to_thread, while a blocking-worker test records peak == 2, checks the executor arguments, and confirms to_thread is not used. Public propagation tests cover full development mode and production fallback with the configured value. Prior failure addressed: test_import_dev_mode_forwards_configured_worker_limit and test_import_production_fallback_forwards_configured_worker_limit verify public propagation. test_dynamic_import_caps_configured_worker_count uses blocking workers and asserts peak == 2 plus executor arguments.

Full details: Test File Naming And Structure

Explanation

The changed backend test files use the required test_*.py pattern and reside under src/lfx/tests/unit. They use pytest classes, fixtures, async markers, parametrization, mocks, and context-managed patching. Test names such as test_component_load_max_workers_reads_operator_environment and test_component_load_max_workers_must_be_positive describe the behavior. The tests cover unset, valid, zero, and negative values, plus configured and default loading paths. No frontend or integration test files were added.

Full details: Excessive Mock Usage Warning

Explanation

No excessive mock usage is introduced. The settings tests construct real Settings objects and use only environment patching. The concurrency test uses a real ThreadPoolExecutor, real worker blocking, and measures actual peak concurrency. Other mocks isolate module discovery, cache access, and async dispatch so the tests can verify forwarding and call selection without importing real component modules. The mocks do not replace the worker-limit behavior under test.

✨ Finishing Touches: 💡 1
🛠️ Fix failing CI checks: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Oct 15, 2026
Add LANGFLOW_COMPONENT_LOAD_MAX_WORKERS to bound component import
concurrency. Unset keeps the existing asyncio.to_thread behavior.

Cover the propagation from import_langflow_components through the dev and
production fallback paths, prove the configured executor caps concurrency,
and document the new tests.

Fixes langflow-ai#11354
@yu1128-L
yu1128-L force-pushed the fix/configurable-component-load-workers-11354 branch from 313f077 to 3b642f7 Compare October 16, 2026 18:55
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Oct 16, 2026
@yu1128-L

Copy link
Copy Markdown
Author

@coderabbitai review

Both pre-merge warnings from the previous review are addressed in 3b642f7:

  • Docstring coverage: added docstrings to the settings-composition tests that were missing them ( est_settings_composition.py).
  • Test quality: added est_import_dev_mode_forwards_configured_worker_limit and est_import_production_fallback_forwards_configured_worker_limit, plus rewrote est_dynamic_import_caps_configured_worker_count to assert peak == 2 via a blocking worker. These cover the public import_langflow_components propagation path the check asked for.

@coderabbitai

coderabbitai Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Oct 16, 2026
@yu1128-L

Copy link
Copy Markdown
Author

CI is green on 3b642f7. The Docker job's first attempt was interrupted by a runner shutdown (the image had already built and Authentication smoke check passed); the �erify or retry job then completed successfully, and the aggregating CI Success gate passed.

Summary of the latest state:

  • All Playwright shards (70/70), Jest, backend unit/integration/CLI/LFX tests, and the bundle suites passed.
  • Ruff check/format and the coverage aggregation jobs passed.

eviewDecision is still REVIEW_REQUIRED, so this is ready for maintainer review.

Happy to adjust anything if the reviewer wants a different default for the worker count.

This branch has not been deployed

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

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant