mirror of
https://dev.azure.com/globalhealthx/EMR/_git/helix-engage-server
synced 2026-05-18 20:08:19 +00:00
fix(flow): serialize per-phone execution to prevent concurrent flows
Two messages arriving close together could start two parallel flow executions for the same phone. The second would create a new session while the first was mid-AI-block, causing duplicate greetings and race conditions. Per-phone async lock ensures sequential execution. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -44,9 +44,28 @@ export class FlowExecutionService {
|
||||
this.auth = apiKey ? `Bearer ${apiKey}` : '';
|
||||
}
|
||||
|
||||
// Per-phone lock to prevent concurrent flow executions
|
||||
private readonly locks = new Map<string, Promise<void>>();
|
||||
|
||||
async handleMessage(message: NormalizedMessage): Promise<void> {
|
||||
const { phone } = message;
|
||||
|
||||
// Serialize executions per phone — prevent two concurrent flows
|
||||
const existing = this.locks.get(phone);
|
||||
const execute = async () => {
|
||||
if (existing) await existing.catch(() => {});
|
||||
await this._handleMessage(message);
|
||||
};
|
||||
const promise = execute();
|
||||
this.locks.set(phone, promise);
|
||||
await promise.finally(() => {
|
||||
if (this.locks.get(phone) === promise) this.locks.delete(phone);
|
||||
});
|
||||
}
|
||||
|
||||
private async _handleMessage(message: NormalizedMessage): Promise<void> {
|
||||
const { phone } = message;
|
||||
|
||||
// 1. Load existing session or start new flow
|
||||
let session = await this.sessions.load(phone);
|
||||
let flow: Flow | null = null;
|
||||
|
||||
Reference in New Issue
Block a user