Refuse a zero concurrency limit instead of reading it as the default
Docs / docs (push) Successful in 23s
Playwright Tests / test-playwright (1, 2) (push) Successful in 3m16s
Playwright Tests / test-playwright (2, 2) (push) Successful in 1m48s
pre-commit / pre-commit (push) Failing after 2m32s
Test Backend / test-backend (push) Successful in 2m38s
Compose Smoke Test / test-compose (push) Successful in 32s
Playwright Tests / merge-reports (push) Successful in 1m9s

FLOW_MAX_WORKERS, FLOW_MAX_CASCADES and FLOW_MAX_RUNS are all pool sizes,
so 0 says neither "none" nor "unlimited" — it is a pool that cannot be
built. They are PositiveInt now, so a 0 fails at startup naming the
setting rather than being swallowed by `max_cascades or MAX_CASCADES`.
The consuming fallbacks take only None as "nobody said": explicit
`is None` in the executor, and no clamp on RunService.parallel.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K1moruzue2kTJd3uVisgNk
This commit is contained in:
2026-08-28 20:00:08 +02:00
co-authored by Claude Opus 5
parent 1feaa1f6cb
commit 7efa75e242
4 changed files with 22 additions and 7 deletions
+3 -1
View File
@@ -769,7 +769,9 @@ class RunService:
# the isolation it wants, minus surviving the process.
self._state_factory = state_factory or (lambda _ns: MemoryState())
self.engine_name = f"{socket.gethostname()}-{os.getpid()}"[:64]
self.parallel = max(1, parallel)
# Taken as written: clamping a 0 up to 1 would hide a limit somebody
# set, and the pool below rejects an unusable one loudly anyway.
self.parallel = parallel
self._pool = ThreadPoolExecutor(
max_workers=self.parallel, thread_name_prefix="run"
)