Skip to content

Engine: parallel-limit semaphores acquired without a cancellation token while the module is already counted as Executing #3792

Description

@thomhurst

ParallelLimitHandler.AcquireParallelLimitAsync/AcquireExecutionTypeLimitAsync call WaitAsync() with no cancellation token, and they run after scheduler.MarkModuleStarted has already transitioned the module to Executing and recorded start metrics (ModuleRunner.cs:134 vs 586-587).

Consequences: (1) during fail-fast shutdown a module blocked on a limiter slot cannot be interrupted — it waits until a slot frees, which never happens if the holder ignores its token and no timeout is configured, hanging the worker pool drain; (2) time spent queued behind the limiter is attributed to execution in metrics/concurrency snapshots and in the scheduler's constraint evaluation, which sees a "running" module that hasn't started.

Fix: pass the worker/engine cancellation token into both WaitAsync calls and consider acquiring the limits before MarkModuleStarted (or recording a separate "slot wait" phase) so state and telemetry reflect reality.

Evidence: src/ModularPipelines/Engine/Execution/ParallelLimitHandler.cs:39,57, src/ModularPipelines/Engine/Execution/ModuleRunner.cs:134,586-587


Raised by the v4 scoping audit round 3 — umbrella #3239.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low: hygiene and nice-to-haves - wheneverbugSomething isn't workingin-progressPicked up by an agent

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions