Skip to content

Commit 078b24f

Browse files
committed
onDrain callback
1 parent 6be7b02 commit 078b24f

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

vscode/core/src/solutionWorkflowOrchestrator.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,42 @@ export class SolutionWorkflowOrchestrator {
130130

131131
// Set up the resolver function
132132
this.state.resolvePendingInteraction = this.createInteractionResolver();
133+
134+
// Register onDrain handler to trigger cleanup when queue empties
135+
// This catches cases where the queue drains naturally without resolver calls
136+
this.queueManager.onDrain(() => {
137+
this.handleQueueDrained();
138+
});
139+
}
140+
141+
/**
142+
* Handle queue drain event - check if cleanup should happen
143+
* Called automatically when the queue becomes empty
144+
*/
145+
private handleQueueDrained(): void {
146+
this.logger.debug("Queue drained, checking cleanup conditions", {
147+
workflowRunCompleted: this.workflowRunCompleted,
148+
pendingInteractionsSize: this.pendingInteractions.size,
149+
isWaitingForUserInteraction: this.state.data.isWaitingForUserInteraction,
150+
isFetchingSolution: this.state.data.isFetchingSolution,
151+
});
152+
153+
// Check all cleanup conditions
154+
const allComplete =
155+
this.pendingInteractions.size === 0 &&
156+
!this.state.data.isWaitingForUserInteraction &&
157+
this.queueManager!.getQueueLength() === 0;
158+
159+
if (allComplete && this.workflowRunCompleted && this.state.data.isFetchingSolution) {
160+
this.logger.info("Queue drained and all conditions met - triggering cleanup");
161+
this.finalCleanup();
162+
} else {
163+
this.logger.debug("Queue drained but not all conditions met for cleanup", {
164+
allComplete,
165+
workflowRunCompleted: this.workflowRunCompleted,
166+
isFetchingSolution: this.state.data.isFetchingSolution,
167+
});
168+
}
133169
}
134170

135171
/**

vscode/core/src/utilities/ModifiedFiles/queueManager.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export class MessageQueueManager {
1212
private isProcessingQueue = false;
1313
private processingTimer: NodeJS.Timeout | null = null;
1414
private logger: Logger;
15+
private onDrainCallback?: () => void;
1516

1617
constructor(
1718
private state: ExtensionState,
@@ -27,6 +28,13 @@ export class MessageQueueManager {
2728
});
2829
}
2930

31+
/**
32+
* Register a callback to be invoked when the queue drains (becomes empty)
33+
*/
34+
onDrain(callback: () => void): void {
35+
this.onDrainCallback = callback;
36+
}
37+
3038
/**
3139
* Adds a message to the queue
3240
*/
@@ -159,6 +167,17 @@ export class MessageQueueManager {
159167
});
160168
} finally {
161169
this.isProcessingQueue = false;
170+
171+
// If queue is now empty and we have a drain callback, invoke it
172+
// This allows the orchestrator to check if cleanup should happen
173+
if (this.messageQueue.length === 0 && this.onDrainCallback) {
174+
this.logger.debug("Queue drained, invoking onDrain callback");
175+
try {
176+
this.onDrainCallback();
177+
} catch (error) {
178+
this.logger.error("Error in onDrain callback:", error);
179+
}
180+
}
162181
}
163182
}
164183

0 commit comments

Comments
 (0)