comq 0.25.0 → 0.25.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "comq",
3
- "version": "0.25.0",
3
+ "version": "0.25.1",
4
4
  "description": "ComQ",
5
5
  "author": {
6
6
  "name": "Artem Gurtovoi",
package/source/channel.js CHANGED
@@ -49,6 +49,9 @@ class Channel {
49
49
  /** @type {Set<Promex>} */
50
50
  #confirmations = new Set()
51
51
 
52
+ /** @type {Set<Promise<void>>} failed messages on their way to a retry or the parking queue */
53
+ #settling = new Set()
54
+
52
55
  #diagnostics = emitter.create()
53
56
 
54
57
  #closed = false
@@ -221,6 +224,10 @@ class Channel {
221
224
 
222
225
  await this.seal()
223
226
 
227
+ // a failed message is moved in two steps, its copy placed and then the original
228
+ // released; a channel closed between them leaves the broker holding both
229
+ await Promise.allSettled(this.#settling)
230
+
224
231
  // a channel that went down with its connection is the outcome this asks for
225
232
  await this.#channel?.close().catch(noop)
226
233
 
@@ -587,7 +594,13 @@ class Channel {
587
594
  } catch (exception) {
588
595
  if (exception?.message === 'Channel closed') { return } // the message is requeued by the broker
589
596
 
590
- await this.#failed(queue, message, exception)
597
+ const settling = this.#failed(queue, message, exception)
598
+
599
+ this.#settling.add(settling)
600
+
601
+ await settling
602
+
603
+ this.#settling.delete(settling)
591
604
  }
592
605
  }
593
606
 
@@ -1251,6 +1251,31 @@ describe('failed messages', () => {
1251
1251
  expect(chan.ack).toHaveBeenCalled()
1252
1252
  })
1253
1253
 
1254
+ it('should release the original before the channel is given back', async () => {
1255
+ await channel.consume(queue, consumer)
1256
+
1257
+ let confirm
1258
+
1259
+ chan.publish.mockImplementationOnce((_0, _1, _2, _3, callback) => (confirm = callback))
1260
+
1261
+ const delivering = deliver(delivery())
1262
+
1263
+ // closed while the copy is on its way: an original still unacknowledged then is
1264
+ // requeued by the broker, and the message is held twice
1265
+ const closing = channel.close()
1266
+
1267
+ await new Promise((resolve) => setImmediate(resolve))
1268
+
1269
+ confirm(null)
1270
+
1271
+ await closing
1272
+ await delivering
1273
+
1274
+ expect(chan.ack).toHaveBeenCalledTimes(1)
1275
+ expect(chan.ack.mock.invocationCallOrder[0])
1276
+ .toBeLessThan(chan.close.mock.invocationCallOrder[0])
1277
+ })
1278
+
1254
1279
  it('should increment the attempt', async () => {
1255
1280
  await channel.consume(queue, consumer)
1256
1281