mirror of
https://github.com/jambonz/sbc-inbound.git
synced 2026-10-04 02:04:22 +00:00
Scale-in completion never happened: app.js holds the placeholder Emitter that autoscale-manager returns synchronously (the real SnsNotifier replaces it later inside an async IIFE), so the completion poller never saw operationalState change; it also called the nonexistent scaleIn() rather than completeScaleIn(). Instances in Terminating:Wait therefore always burned the full lifecycle hook heartbeat timeout. In addition, nothing consumed dryUpCalls: a draining SBC kept accepting new INVITEs sent directly to its public address right up until termination. Changes: - complete the scale-in from within the ScaleIn handler in autoscale-manager, where the real notifier is in scope - while draining, reject new INVITEs with 503 so senders fail over to another SBC (INVITE with Replaces is allowed through since it targets a call already in progress here) - a server may run several sbc-inbound and sbc-outbound processes, and completing the hook when only this process is idle would terminate the instance while sibling processes still have calls; each process now reports its call count to redis (lib/call-count-reporter.js, with a companion change in sbc-outbound) and the draining process completes only when the server-wide count is zero on two consecutive checks, falling back to its own count if no reports are present Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
32 lines
1.2 KiB
JavaScript
32 lines
1.2 KiB
JavaScript
const os = require('os');
|
|
|
|
/**
|
|
* Periodically report this process's count of calls in progress to redis.
|
|
* A server may host several sbc-inbound and sbc-outbound processes; when one
|
|
* of them handles an autoscale drain it needs to know when the entire server
|
|
* has no calls in progress, not just its own process. Each process writes
|
|
* its own count under a per-pid key (with a short expiry, so keys from dead
|
|
* processes evaporate) and registers that key in a per-host set that the
|
|
* draining process can enumerate.
|
|
*/
|
|
const REPORT_INTERVAL = 15000;
|
|
const KEY_EXPIRY_SECS = 120;
|
|
|
|
module.exports = ({logger, addKey, addToSet, getCount}) => {
|
|
const prefix = process.env.JAMBONES_CLUSTER_ID || 'default';
|
|
const setName = `${prefix}:call-count-keys:${os.hostname()}`;
|
|
const key = `${prefix}:call-count:${os.hostname()}:${process.pid}`;
|
|
|
|
const report = () => {
|
|
addKey(key, `${getCount()}`, KEY_EXPIRY_SECS)
|
|
.catch((err) => logger.error({err}, 'call-count-reporter: error writing call count'));
|
|
};
|
|
|
|
addToSet(setName, key)
|
|
.catch((err) => logger.error({err}, `call-count-reporter: error adding ${key} to ${setName}`));
|
|
setInterval(report, REPORT_INTERVAL);
|
|
report();
|
|
|
|
return {key, setName};
|
|
};
|