diff --git a/src/dialer/dial-request.js b/src/dialer/dial-request.js index f2774929..2f97f997 100644 --- a/src/dialer/dial-request.js +++ b/src/dialer/dial-request.js @@ -47,12 +47,11 @@ class DialRequest { const tokenHolder = new FIFO() tokens.forEach(token => tokenHolder.push(token)) const dialAbortControllers = this.addrs.map(() => new AbortController()) - let startedDials = 0 + let completedDials = 0 try { return await pAny(this.addrs.map(async (addr, i) => { const token = await tokenHolder.shift() // get token - startedDials++ let conn try { const signal = dialAbortControllers[i].signal @@ -60,8 +59,9 @@ class DialRequest { // Remove the successful AbortController so it is not aborted dialAbortControllers.splice(i, 1) } finally { - // If we have more dials to make, recycle the token, otherwise release it - if (startedDials < this.addrs.length) { + completedDials++ + // If we have more or equal dials remaining than tokens, recycle the token, otherwise release it + if (this.addrs.length - completedDials >= tokens.length) { tokenHolder.push(token) } else { this.dialer.releaseToken(tokens.splice(tokens.indexOf(token), 1)[0]) diff --git a/test/dialing/dial-request.spec.js b/test/dialing/dial-request.spec.js index d785b000..f88db772 100644 --- a/test/dialing/dial-request.spec.js +++ b/test/dialing/dial-request.spec.js @@ -53,16 +53,11 @@ describe('Dial Request', () => { it('should release tokens when all addr dials have started', async () => { const mockConnection = await createMockConnection() + const firstDials = pDefer() const deferred = pDefer() const actions = { - 1: async () => { - await delay(0) - return Promise.reject(error) - }, - 2: async () => { - await delay(0) - return Promise.reject(error) - }, + 1: () => firstDials.promise, + 2: () => firstDials.promise, 3: () => deferred.promise } const dialAction = (num) => actions[num]() @@ -85,7 +80,11 @@ describe('Dial Request', () => { sinon.spy(dialer, 'releaseToken') dialRequest.run({ signal: controller.signal }) // Let the first dials run - await delay(100) + await delay(0) + + // Finish the first 2 dials + firstDials.reject(error) + await delay(0) // Only 1 dial should remain, so 1 token should have been released expect(actions[1]).to.have.property('callCount', 1) @@ -93,7 +92,7 @@ describe('Dial Request', () => { expect(actions[3]).to.have.property('callCount', 1) expect(dialer.releaseToken).to.have.property('callCount', 1) - // Finish the dial + // Finish the dial and release the 2nd token deferred.resolve(mockConnection) await delay(0) expect(dialer.releaseToken).to.have.property('callCount', 2)