From a9e789f466020c2528c75ddffb7b3be5c99360e0 Mon Sep 17 00:00:00 2001 From: Dave Horton Date: Sat, 2 Oct 2021 12:40:56 -0400 Subject: [PATCH] add support for autoscaling SBC SIP servers; bugfix: synthAudio calls must past stats obj --- lib/tasks/dialogflow/index.js | 3 ++- lib/tasks/lex.js | 3 ++- lib/tasks/say.js | 5 +++-- lib/utils/install-srf-locals.js | 2 ++ lib/utils/sbc-pinger.js | 27 ++++++++++++++++++++------- package-lock.json | 20 +++++++++----------- package.json | 2 +- 7 files changed, 39 insertions(+), 23 deletions(-) diff --git a/lib/tasks/dialogflow/index.js b/lib/tasks/dialogflow/index.js index 9dd624bd..02261a1e 100644 --- a/lib/tasks/dialogflow/index.js +++ b/lib/tasks/dialogflow/index.js @@ -210,6 +210,7 @@ class Dialogflow extends Task { /* if we are using tts and a message was provided, play it out */ if (this.vendor && intent.fulfillmentText && intent.fulfillmentText.length > 0) { const {srf} = cs; + const {stats} = srf.locals; const {synthAudio} = srf.locals.dbHelpers; this.waitingForPlayStart = false; @@ -229,7 +230,7 @@ class Dialogflow extends Task { credentials: this.ttsCredentials }; this.logger.debug({obj}, 'Dialogflow:_onIntent - playing message via tts'); - const {filePath, servedFromCache} = await synthAudio(obj); + const {filePath, servedFromCache} = await synthAudio(stats, obj); if (filePath) cs.trackTmpFile(filePath); if (!this.ttsCredentials && !servedFromCache) cs.billForTts(intent.fulfillmentText.length); diff --git a/lib/tasks/lex.js b/lib/tasks/lex.js index 0d2c9d8e..58df5bce 100644 --- a/lib/tasks/lex.js +++ b/lib/tasks/lex.js @@ -182,12 +182,13 @@ class Lex extends Task { const type = messages[0].type; if (['PlainText', 'SSML'].includes(type) && msg) { const {srf} = cs; + const {stats} = srf.locals; const {synthAudio} = srf.locals.dbHelpers; try { this.logger.debug(`tts with ${this.vendor} ${this.voice}`); // eslint-disable-next-line no-unused-vars - const {filePath, servedFromCache} = await synthAudio({ + const {filePath, servedFromCache} = await synthAudio(stats, { text: msg, vendor: this.vendor, language: this.language, diff --git a/lib/tasks/say.js b/lib/tasks/say.js index b00e3bde..73f3509b 100644 --- a/lib/tasks/say.js +++ b/lib/tasks/say.js @@ -19,7 +19,7 @@ class TaskSay extends Task { const {srf} = cs; const {updateSpeechCredentialLastUsed} = require('../utils/db-utils')(this.logger, srf); - const {writeAlerts, AlertType} = srf.locals; + const {writeAlerts, AlertType, stats} = srf.locals; const {synthAudio} = srf.locals.dbHelpers; const vendor = this.synthesizer.vendor || cs.speechSynthesisVendor; const language = this.synthesizer.language || cs.speechSynthesisLanguage; @@ -27,6 +27,7 @@ class TaskSay extends Task { const salt = cs.callSid; const credentials = cs.getSpeechCredentials(vendor, 'tts'); + this.logger.info({vendor, credentials}, 'Task:say - using vendor'); this.ep = ep; try { if (!credentials) { @@ -40,7 +41,7 @@ class TaskSay extends Task { // synthesize all of the text elements let lastUpdated = false; const filepath = (await Promise.all(this.text.map(async(text) => { - const {filePath, servedFromCache} = await synthAudio({ + const {filePath, servedFromCache} = await synthAudio(stats, { text, vendor, language, diff --git a/lib/utils/install-srf-locals.js b/lib/utils/install-srf-locals.js index b1a85552..5c319454 100644 --- a/lib/utils/install-srf-locals.js +++ b/lib/utils/install-srf-locals.js @@ -135,6 +135,7 @@ function installSrfLocals(srf, logger) { retrieveSet, addToSet, removeFromSet, + monitorSet, pushBack, popFront, removeFromList, @@ -178,6 +179,7 @@ function installSrfLocals(srf, logger) { retrieveSet, addToSet, removeFromSet, + monitorSet, pushBack, popFront, removeFromList, diff --git a/lib/utils/sbc-pinger.js b/lib/utils/sbc-pinger.js index 149fe742..39d0884c 100644 --- a/lib/utils/sbc-pinger.js +++ b/lib/utils/sbc-pinger.js @@ -7,13 +7,15 @@ const debug = require('debug')('jambonz:feature-server'); module.exports = (logger) => { logger = logger || noopLogger; let idxSbc = 0; + let sbcs = []; - assert.ok(process.env.JAMBONES_SBCS, 'missing JAMBONES_SBCS env var'); - const sbcs = process.env.JAMBONES_SBCS - .split(',') - .map((sbc) => sbc.trim()); - assert.ok(sbcs.length, 'JAMBONES_SBCS env var is empty or misconfigured'); - logger.info({sbcs}, 'SBC inventory'); + if (process.env.JAMBONES_SBCS) { + sbcs = process.env.JAMBONES_SBCS + .split(',') + .map((sbc) => sbc.trim()); + assert.ok(sbcs.length, 'JAMBONES_SBCS env var is empty or misconfigured'); + logger.info({sbcs}, 'SBC inventory'); + } // listen for SNS lifecycle changes let lifecycleEmitter = new Emitter(); @@ -96,8 +98,19 @@ module.exports = (logger) => { }, 20000); // initial ping once we are up - setTimeout(() => { + setTimeout(async() => { const {srf} = require('../..'); + + // if SBCs are auto-scaling, monitor them as they come and go + if (!process.env.JAMBONES_SBCS) { + const {monitorSet} = srf.locals.dbHelpers; + const setName = `${(process.env.JAMBONES_CLUSTER_ID || 'default')}:active-sip`; + await monitorSet(setName, 10, (members) => { + sbcs = members; + logger.info(`sbc-pinger: SBC roster has changed, list of active SBCs is now ${sbcs}`); + }); + } + pingProxies(srf); }, 1000); diff --git a/package-lock.json b/package-lock.json index 44f00ffe..2c5c213e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,16 @@ { "name": "jambonz-feature-server", - "version": "0.3.1", + "version": "0.6.6", "lockfileVersion": 2, "requires": true, "packages": { "": { - "version": "0.3.1", + "version": "0.6.6", "license": "MIT", "dependencies": { "@jambonz/db-helpers": "^0.6.13", "@jambonz/mw-registrar": "^0.2.1", - "@jambonz/realtimedb-helpers": "^0.4.1", + "@jambonz/realtimedb-helpers": "^0.4.7", "@jambonz/stats-collector": "^0.1.5", "@jambonz/time-series": "^0.1.5", "aws-sdk": "^2.846.0", @@ -405,13 +405,12 @@ } }, "node_modules/@jambonz/realtimedb-helpers": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@jambonz/realtimedb-helpers/-/realtimedb-helpers-0.4.1.tgz", - "integrity": "sha512-GDZ+VkVkSatAh6rYxapzi3r0k/Lj45mh1LAV6aB8U1kTcm3cD9u8QDBB04JL+seBg9mZmEB5aEiCdE9icOnJew==", + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/@jambonz/realtimedb-helpers/-/realtimedb-helpers-0.4.7.tgz", + "integrity": "sha512-pJ8nhR0t0K5Z9jBxOvQY8/9o3XG497hkeYdgrRm/83igfqOnp2hMrslcSevJPNaZFzlEZZCNpC7g2LcZtXOxhQ==", "dependencies": { "@google-cloud/text-to-speech": "^3.1.3", "@jambonz/promisify-redis": "0.0.6", - "@jambonz/stats-collector": "^0.1.5", "aws-sdk": "^2.840.0", "debug": "^4.3.1", "redis": "^3.0.0" @@ -5075,13 +5074,12 @@ } }, "@jambonz/realtimedb-helpers": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@jambonz/realtimedb-helpers/-/realtimedb-helpers-0.4.1.tgz", - "integrity": "sha512-GDZ+VkVkSatAh6rYxapzi3r0k/Lj45mh1LAV6aB8U1kTcm3cD9u8QDBB04JL+seBg9mZmEB5aEiCdE9icOnJew==", + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/@jambonz/realtimedb-helpers/-/realtimedb-helpers-0.4.7.tgz", + "integrity": "sha512-pJ8nhR0t0K5Z9jBxOvQY8/9o3XG497hkeYdgrRm/83igfqOnp2hMrslcSevJPNaZFzlEZZCNpC7g2LcZtXOxhQ==", "requires": { "@google-cloud/text-to-speech": "^3.1.3", "@jambonz/promisify-redis": "0.0.6", - "@jambonz/stats-collector": "^0.1.5", "aws-sdk": "^2.840.0", "debug": "^4.3.1", "redis": "^3.0.0" diff --git a/package.json b/package.json index 15456c91..0bacda8c 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "dependencies": { "@jambonz/db-helpers": "^0.6.13", "@jambonz/mw-registrar": "^0.2.1", - "@jambonz/realtimedb-helpers": "^0.4.1", + "@jambonz/realtimedb-helpers": "^0.4.7", "@jambonz/stats-collector": "^0.1.5", "@jambonz/time-series": "^0.1.5", "aws-sdk": "^2.846.0",