diff --git a/assets/js/phoenix.js b/assets/js/phoenix.js index 9f56a052d2..78149265a9 100644 --- a/assets/js/phoenix.js +++ b/assets/js/phoenix.js @@ -838,6 +838,7 @@ export class Socket { this.flushSendBuffer() this.reconnectTimer.reset() this.resetHeartbeat() + this.resetChannelTimers() this.stateChangeCallbacks.open.forEach( callback => callback() ) } @@ -986,6 +987,15 @@ export class Socket { } }) } + + /** + * @private + */ + resetChannelTimers() { + this.channels.forEach(channel => { + channel.rejoinTimer.restart() + }) + } } @@ -1346,18 +1356,31 @@ class Timer { reset(){ this.tries = 0 - clearTimeout(this.timer) + this.clearTimer() + } + + restart(){ + const processing = this.timer !== null + this.reset() + if (processing){ + this.scheduleTimeout() + } } /** * Cancels any previous scheduleTimeout and schedules callback */ scheduleTimeout(){ - clearTimeout(this.timer) + this.clearTimer() this.timer = setTimeout(() => { this.tries = this.tries + 1 this.callback() }, this.timerCalc(this.tries + 1)) } + + clearTimer() { + clearTimeout(this.timer) + this.timer = null + } } diff --git a/assets/test/socket_test.js b/assets/test/socket_test.js index 4790db7759..fe38507b5d 100644 --- a/assets/test/socket_test.js +++ b/assets/test/socket_test.js @@ -605,6 +605,25 @@ describe("onConnOpen", () => { assert.ok(spy.calledOnce) }) + it("resets all channel timers and schedules a timeout if the timer was in progress", () => { + const channel = socket.channel("topic", {}) + const channel2 = socket.channel("topic2", {}) + + channel.rejoinTimer.tries = 1 + channel2.rejoinTimer.tries = 2 + channel2.rejoinTimer.scheduleTimeout() + + assert.equal(channel.rejoinTimer.timer, null) + assert.notEqual(channel2.rejoinTimer.timer, null) + + socket.onConnOpen() + + assert.equal(channel.rejoinTimer.tries, 0) + assert.equal(channel2.rejoinTimer.tries, 0) + assert.equal(channel.rejoinTimer.timer, null) + assert.notEqual(channel2.rejoinTimer.timer, null) + }) + it("triggers onOpen callback", () => { const spy = sinon.spy()