Skip to content

Commit 1d9ae05

Browse files
committed
[misc] command queue: never discard a command that has not started
1 parent a666b5e commit 1d9ae05

2 files changed

Lines changed: 32 additions & 2 deletions

File tree

lib/connection.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,7 +1499,7 @@ class Connection extends EventEmitter {
14991499
activeReceiveCmd() {
15001500
let cmd;
15011501
while ((cmd = this.receiveQueue.peekFront())) {
1502-
if (cmd.onPacketReceive) return cmd;
1502+
if (cmd.onPacketReceive !== null) return cmd;
15031503
this.receiveQueue.shift();
15041504
}
15051505
return null;
@@ -1704,7 +1704,7 @@ class Connection extends EventEmitter {
17041704

17051705
//Command in progress => must execute the query,
17061706
//or if no command in progress, can rely on status to know if a query is needed
1707-
if (this.activeReceiveCmd() || this.info.status & ServerStatus.STATUS_IN_TRANS) {
1707+
if (this.receiveQueue.peekFront() || this.info.status & ServerStatus.STATUS_IN_TRANS) {
17081708
const cmd = new Query(resolve, this._logAndReject.bind(this, reject), this.opts, cmdParam);
17091709
this.addCommand(cmd, true);
17101710
} else resolve();

test/unit/connection-command-queue.test.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,36 @@ describe.concurrent('command queue without pipelining (CONJS-361)', () => {
5353
assert.equal(conn.receiveQueue.peekFront(), cmd);
5454
});
5555

56+
// a command is only given its onPacketReceive when it starts, so a command queued behind a big
57+
// send has none at all. Discarding it would lose its response for good: only a command that ended,
58+
// which sets onPacketReceive to null, may be dropped.
59+
test('a command queued but not started yet is never discarded', () => {
60+
const conn = newConn();
61+
const notStarted = new FakeCmd(true);
62+
notStarted.onPacketReceive = undefined; // as built by Query/Execute before start()
63+
conn.receiveQueue.push(notStarted);
64+
65+
assert.equal(conn.activeReceiveCmd(), notStarted, 'a command not started yet is still pending');
66+
assert.equal(conn.receiveQueue.length, 1, 'it must stay queued');
67+
68+
const cmd = new FakeCmd(true);
69+
conn.addCommandEnable(cmd, true);
70+
assert.isFalse(cmd.started, 'nothing may be sent while it waits to start');
71+
});
72+
73+
test('an ended command queued ahead of a not started one is dropped, the other kept', () => {
74+
const conn = newConn();
75+
const ended = new FakeCmd(false); // onPacketReceive === null
76+
const notStarted = new FakeCmd(true);
77+
notStarted.onPacketReceive = undefined;
78+
conn.receiveQueue.push(ended);
79+
conn.receiveQueue.push(notStarted);
80+
81+
assert.equal(conn.activeReceiveCmd(), notStarted);
82+
assert.equal(conn.receiveQueue.length, 1);
83+
assert.equal(conn.receiveQueue.peekFront(), notStarted);
84+
});
85+
5686
test('waits while a command is still receiving packets', () => {
5787
const conn = newConn();
5888
const active = new FakeCmd(true);

0 commit comments

Comments
 (0)