Skip to content
This repository was archived by the owner on Mar 17, 2026. It is now read-only.

Commit e59f8ec

Browse files
callmehiphopJustinBeckwith
authored andcommitted
fix: ignore messages that come in after close (#485)
1 parent 58ea4b4 commit e59f8ec

5 files changed

Lines changed: 53 additions & 29 deletions

File tree

src/lease-manager.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,9 @@ export class LeaseManager extends EventEmitter {
216216
* @param {Message} message The message to emit.
217217
*/
218218
private _dispense(message: Message): void {
219-
process.nextTick(() => this._subscriber.emit('message', message));
219+
if (this._subscriber.isOpen) {
220+
process.nextTick(() => this._subscriber.emit('message', message));
221+
}
220222
}
221223
/**
222224
* Loops through inventory and extends the deadlines for any messages that

src/subscriber.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -365,13 +365,17 @@ export class Subscriber extends EventEmitter {
365365
*
366366
* @private
367367
*/
368-
private _onData(response: PullResponse): void {
369-
response.receivedMessages.forEach((data: ReceivedMessage) => {
368+
private _onData({receivedMessages}: PullResponse): void {
369+
for (const data of receivedMessages) {
370370
const message = new Message(this, data);
371371

372-
message.modAck(this.ackDeadline);
373-
this._inventory.add(message);
374-
});
372+
if (this.isOpen) {
373+
message.modAck(this.ackDeadline);
374+
this._inventory.add(message);
375+
} else {
376+
message.nack();
377+
}
378+
}
375379
}
376380

377381
/**

system-test/pubsub.ts

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -415,11 +415,8 @@ describe('pubsub', () => {
415415
subscription.on('message', ack);
416416

417417
function ack(message) {
418-
// remove listener to we only ack first message
419-
subscription.removeListener('message', ack);
420-
421418
message.ack();
422-
setTimeout(() => subscription.close(done), 2500);
419+
subscription.close(done);
423420
}
424421
});
425422

@@ -430,11 +427,8 @@ describe('pubsub', () => {
430427
subscription.on('message', nack);
431428

432429
function nack(message) {
433-
// remove listener to we only ack first message
434-
subscription.removeListener('message', nack);
435-
436430
message.nack();
437-
setTimeout(() => subscription.close(done), 2500);
431+
subscription.close(done);
438432
}
439433
});
440434

@@ -588,36 +582,32 @@ describe('pubsub', () => {
588582
let subscription;
589583
let snapshot;
590584

591-
function deleteAllSnapshots() {
592-
// tslint:disable-next-line no-any
593-
return (pubsub.getSnapshots() as any).then(data => {
594-
return Promise.all(data[0].map(snapshot => {
595-
return snapshot.delete();
596-
}));
597-
});
585+
function getSnapshotName({name}) {
586+
return name.split('/').pop();
598587
}
599588

600589
before(async () => {
601590
topic = pubsub.topic(generateTopicName());
602591
subscription = topic.subscription(generateSubName());
603592
snapshot = subscription.snapshot(SNAPSHOT_NAME);
604593

605-
await deleteAllSnapshots();
606594
await topic.create();
607595
await subscription.create();
608596
await snapshot.create();
609597
});
610598

611599
after(async () => {
612-
await deleteAllSnapshots();
600+
await snapshot.delete();
601+
await subscription.delete();
613602
await topic.delete();
614603
});
615604

616605
it('should get a list of snapshots', done => {
617606
pubsub.getSnapshots((err, snapshots) => {
618607
assert.ifError(err);
619-
assert.strictEqual(snapshots.length, 1);
620-
assert.strictEqual(snapshots[0].name.split('/').pop(), SNAPSHOT_NAME);
608+
assert(snapshots.length > 0);
609+
const names = snapshots.map(getSnapshotName);
610+
assert(names.includes(SNAPSHOT_NAME));
621611
done();
622612
});
623613
});
@@ -633,9 +623,9 @@ describe('pubsub', () => {
633623
snapshots.push(snapshot);
634624
})
635625
.on('end', () => {
636-
assert.strictEqual(snapshots.length, 1);
637-
assert.strictEqual(
638-
snapshots[0].name.split('/').pop(), SNAPSHOT_NAME);
626+
assert(snapshots.length > 0);
627+
const names = snapshots.map(getSnapshotName);
628+
assert(names.includes(SNAPSHOT_NAME));
639629
done();
640630
});
641631
});

test/lease-manager.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const fakeos = {
2626

2727
class FakeSubscriber extends EventEmitter {
2828
ackDeadline = 10;
29+
isOpen = true;
2930
modAckLatency = 2000;
3031
async modAck(message: FakeMessage, deadline: number): Promise<void> {}
3132
}
@@ -140,7 +141,7 @@ describe('LeaseManager', () => {
140141
});
141142

142143
it('should not dispatch the message if the inventory is full', done => {
143-
const message = new FakeMessage();
144+
const fakeMessage = new FakeMessage();
144145

145146
leaseManager.isFull = () => true;
146147
leaseManager.setOptions({allowExcessMessages: false});
@@ -149,6 +150,21 @@ describe('LeaseManager', () => {
149150
done(new Error('Test should not have dispatched message.'));
150151
});
151152

153+
leaseManager.add(fakeMessage);
154+
setImmediate(done);
155+
});
156+
157+
it('should not dispatch the message if the sub closes', done => {
158+
const fakeMessage = new FakeMessage();
159+
160+
leaseManager.isFull = () => false;
161+
162+
subscriber.isOpen = false;
163+
subscriber.on('message', () => {
164+
done(new Error('Test should not have dispatched message.'));
165+
});
166+
167+
leaseManager.add(fakeMessage);
152168
setImmediate(done);
153169
});
154170

test/subscriber.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,18 @@ describe('Subscriber', () => {
320320
subscriber.close();
321321
});
322322

323+
it('should nack any messages that come in after', () => {
324+
const stream: FakeMessageStream = stubs.get('messageStream');
325+
const stub = sandbox.stub(subscriber, 'nack');
326+
const pullResponse = {receivedMessages: [RECEIVED_MESSAGE]};
327+
328+
subscriber.close();
329+
stream.emit('data', pullResponse);
330+
331+
const [{ackId}] = stub.lastCall.args;
332+
assert.strictEqual(ackId, RECEIVED_MESSAGE.ackId);
333+
});
334+
323335
describe('flushing the queues', () => {
324336
it('should wait for any pending acks', async () => {
325337
const ackQueue: FakeAckQueue = stubs.get('ackQueue');

0 commit comments

Comments
 (0)