elsa-core/test/unit/Elsa.Workflows.Runtime.UnitTests/Quiescence
Sipke Schoorstra f477fc8b07
fix(runtime): bound concurrent pre-cancel snapshot Finds during drain (#8113)
* fix(runtime): bound concurrent pre-cancel snapshot Finds during drain

Unbounded Task.WhenAll of per-cycle Finds self-contends under large
live-cycle N: more 250ms timeouts, more drainInduced excludes, more
Interrupted misses. Cap snapshot Finds at 16. The 250ms budget still
starts only after a slot is acquired so queued Finds are not fail-open
excluded by waiting.

Phase C stays sequential. No store-contract change.

Closes #8083

Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>

* fix(runtime): exclude null pre-cancel snapshots from drainInduced

A successful Find that returns no row is unknown pre-state, not a
confirmed non-Cancelled snapshot. Joining drainInduced let Phase C
rewrite a later Finished/Cancelled as Interrupted. Timeout/error
already excluded; null now does too.

Closes nothing extra; keeps #8083 fail-open exclude.

Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>

* fix(runtime): promote null snapshot after Phase A force-cancel

A successful pre-cancel Find that returns no row is not a persisted user-cancel, but excluding it from drainInduced skipped Interrupted persist after deadline-breach force-cancel of a live cycle (DeadlineBreachPersistsInterrupted). Join drainInduced only after we ourselves cancel that handle. Timeout/error and confirmed Cancelled snapshots stay excluded.

Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>

* fix(runtime): promote null snapshot only when TryCancel transitions

Cancel() is a no-op on an already-disposed handle, so treating every Cancel() call as drain-induced could rewrite a Finished/Cancelled row the runner committed while snapshot was in flight. TryCancel reports a real transition; only those ids join drainInduced after a null Find.

Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-09-13 17:18:35 +02:00
..
DrainOrchestratorPauseTests.cs Graceful shutdown for the workflow runtime (drain, pause, recover) (#7424) 2026-05-02 19:27:08 +02:00
DrainOrchestratorTestsBase.cs Graceful shutdown for the workflow runtime (drain, pause, recover) (#7424) 2026-05-02 19:27:08 +02:00
DrainOrchestratorWaitTests.cs fix(runtime): bound concurrent pre-cancel snapshot Finds during drain (#8113) 2026-09-13 17:18:35 +02:00
ExecutionCycleRegistryTests.cs fix(runtime): bound concurrent pre-cancel snapshot Finds during drain (#8113) 2026-09-13 17:18:35 +02:00
IngressSourceRegistryTests.cs Graceful shutdown for the workflow runtime (drain, pause, recover) (#7424) 2026-05-02 19:27:08 +02:00
QuiescenceSignalPersistenceTests.cs Refactor QuiescenceSignal to inject IServiceScopeFactory, enhance tenant ID handling, and expand unit tests with DI capabilities. 2026-05-03 17:56:37 +02:00
QuiescenceSignalTests.cs Graceful shutdown for the workflow runtime (drain, pause, recover) (#7424) 2026-05-02 19:27:08 +02:00