Skip to content

Commit b80fc95

Browse files
committed
do not clear pending actions on completing
1 parent 75ed10c commit b80fc95

File tree

2 files changed

+29
-22
lines changed

2 files changed

+29
-22
lines changed

packages/durabletask-js/src/worker/runtime-orchestration-context.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ export class RuntimeOrchestrationContext extends OrchestrationContext {
146146

147147
this._isComplete = true;
148148
this._completionStatus = status;
149-
this._pendingActions = {}; // Clear any pending actions
149+
// Note: Do NOT clear pending actions here - fire-and-forget actions like sendEvent
150+
// must be preserved and returned alongside the complete action
150151

151152
this._result = result;
152153

@@ -168,7 +169,8 @@ export class RuntimeOrchestrationContext extends OrchestrationContext {
168169

169170
this._isComplete = true;
170171
this._completionStatus = pb.OrchestrationStatus.ORCHESTRATION_STATUS_FAILED;
171-
this._pendingActions = {}; // Cancel any pending actions
172+
// Note: Do NOT clear pending actions here - fire-and-forget actions like sendEvent
173+
// must be preserved and returned alongside the complete action
172174

173175
const action = ph.newCompleteOrchestrationAction(
174176
this.nextSequenceNumber(),

packages/durabletask-js/test/orchestration_context_methods.spec.ts

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -130,25 +130,20 @@ describe("OrchestrationContext.sendEvent", () => {
130130
const executor = new OrchestrationExecutor(registry);
131131
const result = await executor.execute(TEST_INSTANCE_ID, [], newEvents);
132132

133-
// The orchestration completes, but there should be a send event action before that
134-
// Note: the executor returns only the final actions, so we check what was scheduled
135-
expect(result.actions.length).toBeGreaterThanOrEqual(1);
136-
137-
// Check if there's a send event action
138-
let hasSendEventAction = false;
139-
for (const action of result.actions) {
140-
if (action.hasSendevent()) {
141-
hasSendEventAction = true;
142-
const sendEvent = action.getSendevent();
143-
expect(sendEvent?.getInstance()?.getInstanceid()).toEqual("target-instance-id");
144-
expect(sendEvent?.getName()).toEqual("my-event");
145-
expect(sendEvent?.getData()?.getValue()).toEqual(JSON.stringify({ data: "value" }));
146-
break;
147-
}
148-
}
149-
// If no send event action found in actions, check the complete action
150-
// send event is a fire-and-forget action, so it should be present
151-
expect(hasSendEventAction || result.actions.length >= 1).toBeTruthy();
133+
// Should have 2 actions: sendEvent (fire-and-forget) + completeOrchestration
134+
expect(result.actions.length).toEqual(2);
135+
136+
// Find and verify the sendEvent action
137+
const sendEventAction = result.actions.find((a) => a.hasSendevent());
138+
expect(sendEventAction).toBeDefined();
139+
const sendEvent = sendEventAction?.getSendevent();
140+
expect(sendEvent?.getInstance()?.getInstanceid()).toEqual("target-instance-id");
141+
expect(sendEvent?.getName()).toEqual("my-event");
142+
expect(sendEvent?.getData()?.getValue()).toEqual(JSON.stringify({ data: "value" }));
143+
144+
// Verify the complete action is also present
145+
const completeAction = result.actions.find((a) => a.hasCompleteorchestration());
146+
expect(completeAction).toBeDefined();
152147
});
153148

154149
it("should create a SendEvent action without data", async () => {
@@ -166,7 +161,17 @@ describe("OrchestrationContext.sendEvent", () => {
166161
const executor = new OrchestrationExecutor(registry);
167162
const result = await executor.execute(TEST_INSTANCE_ID, [], newEvents);
168163

169-
expect(result.actions.length).toBeGreaterThanOrEqual(1);
164+
// Should have 2 actions: sendEvent (fire-and-forget) + completeOrchestration
165+
expect(result.actions.length).toEqual(2);
166+
167+
// Find and verify the sendEvent action
168+
const sendEventAction = result.actions.find((a) => a.hasSendevent());
169+
expect(sendEventAction).toBeDefined();
170+
const sendEvent = sendEventAction?.getSendevent();
171+
expect(sendEvent?.getInstance()?.getInstanceid()).toEqual("target-instance-id");
172+
expect(sendEvent?.getName()).toEqual("signal-event");
173+
// No data should be set (or empty)
174+
expect(sendEvent?.getData()?.getValue() ?? "").toEqual("");
170175
});
171176
});
172177

0 commit comments

Comments
 (0)