Problem
The InMemoryOrchestrationBackend.suspend() and resume() methods queue the appropriate SuspendEvent/ResumeEvent history events but never update instance.status. This causes getOrchestrationState() to return incorrect runtime status:
- After calling
suspend(), status remains RUNNING instead of SUSPENDED
- After calling
resume(), status remains SUSPENDED instead of RUNNING
Files: packages/durabletask-js/src/testing/in-memory-backend.ts, lines 168–203
Root Cause
In the real DTS sidecar, the suspend/resume RPCs immediately transition the orchestration status. The executor does not produce a COMPLETEORCHESTRATION action for suspend/resume — it only sets an internal _isSuspended flag to buffer/unbuffer events. The in-memory backend relies on processCompleteOrchestrationAction to update status, but since no completion action is generated for suspend/resume, the status was never updated.
Proposed Fix
- Set
instance.status = ORCHESTRATION_STATUS_SUSPENDED in suspend() to match real sidecar behavior
- Transition
instance.status from SUSPENDED back to RUNNING in resume()
- Call
notifyWaiters() from both methods so waitForState() predicates checking for SUSPENDED status are properly triggered
Impact
- Severity: Medium — affects testing accuracy. Tests using the in-memory backend observe incorrect
RUNNING status after suspend, which differs from real sidecar behavior.
- Affected scenarios: Any test checking
OrchestrationStatus.SUSPENDED via getOrchestrationState() or waitForState() after calling suspend().
- Risk: Low — change is scoped to the test infrastructure (
InMemoryOrchestrationBackend), not the production gRPC path.
Problem
The
InMemoryOrchestrationBackend.suspend()andresume()methods queue the appropriateSuspendEvent/ResumeEventhistory events but never updateinstance.status. This causesgetOrchestrationState()to return incorrect runtime status:suspend(), status remainsRUNNINGinstead ofSUSPENDEDresume(), status remainsSUSPENDEDinstead ofRUNNINGFiles:
packages/durabletask-js/src/testing/in-memory-backend.ts, lines 168–203Root Cause
In the real DTS sidecar, the suspend/resume RPCs immediately transition the orchestration status. The executor does not produce a
COMPLETEORCHESTRATIONaction for suspend/resume — it only sets an internal_isSuspendedflag to buffer/unbuffer events. The in-memory backend relies onprocessCompleteOrchestrationActionto update status, but since no completion action is generated for suspend/resume, the status was never updated.Proposed Fix
instance.status = ORCHESTRATION_STATUS_SUSPENDEDinsuspend()to match real sidecar behaviorinstance.statusfromSUSPENDEDback toRUNNINGinresume()notifyWaiters()from both methods sowaitForState()predicates checking forSUSPENDEDstatus are properly triggeredImpact
RUNNINGstatus after suspend, which differs from real sidecar behavior.OrchestrationStatus.SUSPENDEDviagetOrchestrationState()orwaitForState()after callingsuspend().InMemoryOrchestrationBackend), not the production gRPC path.