fix bug where play incorrectly plays again after response received (#786)

* fix bug where play incorrectly plays again after response received

* wip

* fix race condition where bot delay audio kcks off same instant we receive commands
This commit is contained in:
Dave Horton
2024-06-25 12:25:55 -04:00
committed by GitHub
parent 2f3ef1654a
commit be9c3406c1

View File

@@ -2,6 +2,7 @@ const makeTask = require('../tasks/make_task');
const Emitter = require('events'); const Emitter = require('events');
const { normalizeJambones } = require('@jambonz/verb-specifications'); const { normalizeJambones } = require('@jambonz/verb-specifications');
const {TaskName} = require('../utils/constants'); const {TaskName} = require('../utils/constants');
const assert = require('assert');
/** /**
* ActionHookDelayProcessor * ActionHookDelayProcessor
@@ -21,6 +22,7 @@ class ActionHookDelayProcessor extends Emitter {
super(); super();
this.logger = logger; this.logger = logger;
this.cs = cs; this.cs = cs;
this._active = false;
const enabled = this.init(opts); const enabled = this.init(opts);
if (enabled && (!this.actions || !Array.isArray(this.actions) || this.actions.length === 0)) { if (enabled && (!this.actions || !Array.isArray(this.actions) || this.actions.length === 0)) {
@@ -60,10 +62,12 @@ class ActionHookDelayProcessor extends Emitter {
start() { start() {
this.logger.debug('ActionHookDelayProcessor#start'); this.logger.debug('ActionHookDelayProcessor#start');
if (this._noResponseTimer) { if (this._active) {
this.logger.debug('ActionHookDelayProcessor#start: already started due to prior gather which is continuing'); this.logger.debug('ActionHookDelayProcessor#start: already started due to prior gather which is continuing');
return; return;
} }
assert(!this._noResponseTimer);
this._active = true;
this._retryCount = 0; this._retryCount = 0;
const timeoutMs = this.noResponseTimeout === 0 ? 1 : this.noResponseTimeout * 1000; const timeoutMs = this.noResponseTimeout === 0 ? 1 : this.noResponseTimeout * 1000;
this._noResponseTimer = setTimeout(this._onNoResponseTimer.bind(this), timeoutMs); this._noResponseTimer = setTimeout(this._onNoResponseTimer.bind(this), timeoutMs);
@@ -76,6 +80,8 @@ class ActionHookDelayProcessor extends Emitter {
async stop() { async stop() {
this.logger.debug('ActionHookDelayProcessor#stop'); this.logger.debug('ActionHookDelayProcessor#stop');
this._active = false;
if (this._noResponseTimer) { if (this._noResponseTimer) {
clearTimeout(this._noResponseTimer); clearTimeout(this._noResponseTimer);
this._noResponseTimer = null; this._noResponseTimer = null;
@@ -127,6 +133,16 @@ class ActionHookDelayProcessor extends Emitter {
return; return;
} }
this.ep.once('playback-start', (evt) => {
this.logger.debug({evt}, 'got playback-start');
if (!this._active) {
this.logger.info({evt}, 'ActionHookDelayProcessor#_onNoResponseTimer: killing audio immediately');
this.ep.api('uuid_break', this.ep.uuid)
.catch((err) => this.logger.info(err,
'ActionHookDelayProcessor#_onNoResponseTimer Error killing audio'));
}
});
this.ep.once('playback-stop', (evt) => { this.ep.once('playback-stop', (evt) => {
this._taskInProgress = null; this._taskInProgress = null;
if (this._sayResolver) { if (this._sayResolver) {
@@ -137,7 +153,7 @@ class ActionHookDelayProcessor extends Emitter {
} }
else { else {
/* possibly start the no response timer again */ /* possibly start the no response timer again */
if (this.retries > 0 && this._retryCount < this.retries && this.noResponseTimeout > 0) { if (this._active && this.retries > 0 && this._retryCount < this.retries && this.noResponseTimeout > 0) {
this.logger.debug({evt}, 'ActionHookDelayProcessor#_onNoResponseTimer: playback-stop on play/say action'); this.logger.debug({evt}, 'ActionHookDelayProcessor#_onNoResponseTimer: playback-stop on play/say action');
const timeoutMs = this.noResponseTimeout * 1000; const timeoutMs = this.noResponseTimeout * 1000;
this._noResponseTimer = setTimeout(this._onNoResponseTimer.bind(this), timeoutMs); this._noResponseTimer = setTimeout(this._onNoResponseTimer.bind(this), timeoutMs);
@@ -149,6 +165,7 @@ class ActionHookDelayProcessor extends Emitter {
} }
_onNoResponseGiveUpTimer() { _onNoResponseGiveUpTimer() {
this._active = false;
this.logger.info('ActionHookDelayProcessor#_onNoResponseGiveUpTimer'); this.logger.info('ActionHookDelayProcessor#_onNoResponseGiveUpTimer');
this.stop().catch((err) => {}); this.stop().catch((err) => {});
this.emit('giveup'); this.emit('giveup');