fix(voice-call): skip stale calls on load to prevent stuck concurrent limit
When the gateway restarts, loadActiveCalls() reloads non-terminal calls from calls.jsonl. However, these calls may have already ended (e.g., Twilio timed them out) and are now stale. This causes the concurrent call limit to be reached with phantom calls that can never be cleared. Fix: Skip loading calls that are older than maxDurationSeconds, as they cannot possibly still be active. Fixes calls getting stuck in 'initiated' state after gateway restarts.
This commit is contained in:
parent
83de980d6c
commit
c4ac0d2722
@ -830,6 +830,10 @@ export class CallManager {
|
|||||||
const logPath = path.join(this.storePath, "calls.jsonl");
|
const logPath = path.join(this.storePath, "calls.jsonl");
|
||||||
if (!fs.existsSync(logPath)) return;
|
if (!fs.existsSync(logPath)) return;
|
||||||
|
|
||||||
|
// Calls older than maxDurationSeconds are definitely stale
|
||||||
|
const maxAgeMs = this.config.maxDurationSeconds * 1000;
|
||||||
|
const now = Date.now();
|
||||||
|
|
||||||
// Read file synchronously and parse lines
|
// Read file synchronously and parse lines
|
||||||
const content = fs.readFileSync(logPath, "utf-8");
|
const content = fs.readFileSync(logPath, "utf-8");
|
||||||
const lines = content.split("\n");
|
const lines = content.split("\n");
|
||||||
@ -847,18 +851,28 @@ export class CallManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only keep non-terminal calls
|
// Only keep non-terminal calls that aren't stale
|
||||||
for (const [callId, call] of callMap) {
|
for (const [callId, call] of callMap) {
|
||||||
if (!TerminalStates.has(call.state)) {
|
// Skip terminal states
|
||||||
this.activeCalls.set(callId, call);
|
if (TerminalStates.has(call.state)) continue;
|
||||||
// Populate providerCallId mapping for lookups
|
|
||||||
if (call.providerCallId) {
|
// Skip stale calls (older than max duration)
|
||||||
this.providerCallIdMap.set(call.providerCallId, callId);
|
const callAge = now - call.startedAt;
|
||||||
}
|
if (callAge > maxAgeMs) {
|
||||||
// Populate processed event IDs
|
console.log(
|
||||||
for (const eventId of call.processedEventIds) {
|
`[voice-call] Skipping stale call ${callId} (age: ${Math.round(callAge / 1000)}s, max: ${this.config.maxDurationSeconds}s)`,
|
||||||
this.processedEventIds.add(eventId);
|
);
|
||||||
}
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.activeCalls.set(callId, call);
|
||||||
|
// Populate providerCallId mapping for lookups
|
||||||
|
if (call.providerCallId) {
|
||||||
|
this.providerCallIdMap.set(call.providerCallId, callId);
|
||||||
|
}
|
||||||
|
// Populate processed event IDs
|
||||||
|
for (const eventId of call.processedEventIds) {
|
||||||
|
this.processedEventIds.add(eventId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user