1
0
mirror of https://github.com/redis/node-redis.git synced 2025-08-10 11:43:01 +03:00

fix client pubsub and uncomment tests

This commit is contained in:
Leibale
2023-12-05 12:05:12 -05:00
parent 0b3d5fa9e0
commit b99502b874
3 changed files with 190 additions and 191 deletions

View File

@@ -211,9 +211,7 @@ export default class RedisCommandsQueue {
signal.addEventListener('abort', value.abort.listener, { once: true }); signal.addEventListener('abort', value.abort.listener, { once: true });
} }
node = options?.asap ? node = this._toWrite.add(value, options?.asap);
this._toWrite.unshift(value) :
this._toWrite.push(value);
}); });
} }
@@ -272,7 +270,7 @@ export default class RedisCommandsQueue {
if (command === undefined) return; if (command === undefined) return;
return new Promise<void>((resolve, reject) => { return new Promise<void>((resolve, reject) => {
(asap ? this._toWrite.unshift : this._toWrite.push)({ this._toWrite.add({
args: command.args, args: command.args,
chainId: undefined, chainId: undefined,
abort: undefined, abort: undefined,
@@ -287,7 +285,7 @@ export default class RedisCommandsQueue {
}, },
channelsCounter: command.channelsCounter, channelsCounter: command.channelsCounter,
typeMapping: PUSH_TYPE_MAPPING typeMapping: PUSH_TYPE_MAPPING
}); }, asap);
}); });
} }

View File

@@ -525,222 +525,217 @@ describe('Client', () => {
assert.deepEqual(map, results); assert.deepEqual(map, results);
}, GLOBAL.SERVERS.OPEN); }, GLOBAL.SERVERS.OPEN);
// describe('PubSub', () => { describe('PubSub', () => {
// testUtils.testWithClient('should be able to publish and subscribe to messages', async publisher => { testUtils.testWithClient('should be able to publish and subscribe to messages', async publisher => {
// function assertStringListener(message: string, channel: string) { function assertStringListener(message: string, channel: string) {
// assert.equal(typeof message, 'string'); assert.equal(typeof message, 'string');
// assert.equal(typeof channel, 'string'); assert.equal(typeof channel, 'string');
// } }
// function assertBufferListener(message: Buffer, channel: Buffer) { function assertBufferListener(message: Buffer, channel: Buffer) {
// assert.ok(message instanceof Buffer); assert.ok(message instanceof Buffer);
// assert.ok(channel instanceof Buffer); assert.ok(channel instanceof Buffer);
// } }
// const subscriber = publisher.duplicate(); const subscriber = await publisher.duplicate().connect();
// await subscriber.connect(); try {
const channelListener1 = spy(assertBufferListener),
channelListener2 = spy(assertStringListener),
patternListener = spy(assertStringListener);
// try { await Promise.all([
// const channelListener1 = spy(assertBufferListener), subscriber.subscribe('channel', channelListener1, true),
// channelListener2 = spy(assertStringListener), subscriber.subscribe('channel', channelListener2),
// patternListener = spy(assertStringListener); subscriber.pSubscribe('channel*', patternListener)
]);
await Promise.all([
waitTillBeenCalled(channelListener1),
waitTillBeenCalled(channelListener2),
waitTillBeenCalled(patternListener),
publisher.publish(Buffer.from('channel'), Buffer.from('message'))
]);
assert.ok(channelListener1.calledOnceWithExactly(Buffer.from('message'), Buffer.from('channel')));
assert.ok(channelListener2.calledOnceWithExactly('message', 'channel'));
assert.ok(patternListener.calledOnceWithExactly('message', 'channel'));
// await Promise.all([ await subscriber.unsubscribe('channel', channelListener1, true);
// subscriber.subscribe('channel', channelListener1, true), await Promise.all([
// subscriber.subscribe('channel', channelListener2), waitTillBeenCalled(channelListener2),
// subscriber.pSubscribe('channel*', patternListener) waitTillBeenCalled(patternListener),
// ]); publisher.publish('channel', 'message')
// await Promise.all([ ]);
// waitTillBeenCalled(channelListener1), assert.ok(channelListener1.calledOnce);
// waitTillBeenCalled(channelListener2), assert.ok(channelListener2.calledTwice);
// waitTillBeenCalled(patternListener), assert.ok(channelListener2.secondCall.calledWithExactly('message', 'channel'));
// publisher.publish(Buffer.from('channel'), Buffer.from('message')) assert.ok(patternListener.calledTwice);
// ]); assert.ok(patternListener.secondCall.calledWithExactly('message', 'channel'));
await subscriber.unsubscribe('channel');
await Promise.all([
waitTillBeenCalled(patternListener),
publisher.publish('channel', 'message')
]);
assert.ok(channelListener1.calledOnce);
assert.ok(channelListener2.calledTwice);
assert.ok(patternListener.calledThrice);
assert.ok(patternListener.thirdCall.calledWithExactly('message', 'channel'));
// assert.ok(channelListener1.calledOnceWithExactly(Buffer.from('message'), Buffer.from('channel'))); await subscriber.pUnsubscribe();
// assert.ok(channelListener2.calledOnceWithExactly('message', 'channel')); await publisher.publish('channel', 'message');
// assert.ok(patternListener.calledOnceWithExactly('message', 'channel')); assert.ok(channelListener1.calledOnce);
assert.ok(channelListener2.calledTwice);
assert.ok(patternListener.calledThrice);
// await subscriber.unsubscribe('channel', channelListener1, true); // should be able to send commands when unsubsribed from all channels (see #1652)
// await Promise.all([ await assert.doesNotReject(subscriber.ping());
// waitTillBeenCalled(channelListener2), } finally {
// waitTillBeenCalled(patternListener), subscriber.destroy();
// publisher.publish('channel', 'message') }
// ]); }, GLOBAL.SERVERS.OPEN);
// assert.ok(channelListener1.calledOnce);
// assert.ok(channelListener2.calledTwice);
// assert.ok(channelListener2.secondCall.calledWithExactly('message', 'channel'));
// assert.ok(patternListener.calledTwice);
// assert.ok(patternListener.secondCall.calledWithExactly('message', 'channel'));
// await subscriber.unsubscribe('channel');
// await Promise.all([
// waitTillBeenCalled(patternListener),
// publisher.publish('channel', 'message')
// ]);
// assert.ok(channelListener1.calledOnce);
// assert.ok(channelListener2.calledTwice);
// assert.ok(patternListener.calledThrice);
// assert.ok(patternListener.thirdCall.calledWithExactly('message', 'channel'));
// await subscriber.pUnsubscribe();
// await publisher.publish('channel', 'message');
// assert.ok(channelListener1.calledOnce);
// assert.ok(channelListener2.calledTwice);
// assert.ok(patternListener.calledThrice);
// // should be able to send commands when unsubsribed from all channels (see #1652)
// await assert.doesNotReject(subscriber.ping());
// } finally {
// await subscriber.disconnect();
// }
// }, GLOBAL.SERVERS.OPEN);
// testUtils.testWithClient('should resubscribe', async publisher => { testUtils.testWithClient('should resubscribe', async publisher => {
// const subscriber = publisher.duplicate(); const subscriber = await publisher.duplicate().connect();
// await subscriber.connect(); try {
const channelListener = spy();
await subscriber.subscribe('channel', channelListener);
// try { const patternListener = spy();
// const channelListener = spy(); await subscriber.pSubscribe('channe*', patternListener);
// await subscriber.subscribe('channel', channelListener);
// const patternListener = spy(); await Promise.all([
// await subscriber.pSubscribe('channe*', patternListener); once(subscriber, 'error'),
publisher.clientKill({
filter: 'SKIPME',
skipMe: true
})
]);
// await Promise.all([ await once(subscriber, 'ready');
// once(subscriber, 'error'),
// publisher.clientKill({
// filter: ClientKillFilters.SKIP_ME,
// skipMe: true
// })
// ]);
// await once(subscriber, 'ready'); await Promise.all([
waitTillBeenCalled(channelListener),
waitTillBeenCalled(patternListener),
publisher.publish('channel', 'message')
]);
} finally {
subscriber.destroy();
}
}, GLOBAL.SERVERS.OPEN);
// await Promise.all([ testUtils.testWithClient('should not fail when message arrives right after subscribe', async publisher => {
// waitTillBeenCalled(channelListener), const subscriber = await publisher.duplicate().connect();
// waitTillBeenCalled(patternListener),
// publisher.publish('channel', 'message')
// ]);
// } finally {
// await subscriber.disconnect();
// }
// }, GLOBAL.SERVERS.OPEN);
// testUtils.testWithClient('should not fail when message arrives right after subscribe', async publisher => { try {
// const subscriber = publisher.duplicate(); await assert.doesNotReject(Promise.all([
subscriber.subscribe('channel', () => {
// noop
}),
publisher.publish('channel', 'message')
]));
} finally {
subscriber.destroy();
}
}, GLOBAL.SERVERS.OPEN);
// await subscriber.connect(); testUtils.testWithClient('should be able to quit in PubSub mode', async client => {
await client.subscribe('channel', () => {
// noop
});
// try { await assert.doesNotReject(client.quit());
// await assert.doesNotReject(Promise.all([
// subscriber.subscribe('channel', () => {
// // noop
// }),
// publisher.publish('channel', 'message')
// ]));
// } finally {
// await subscriber.disconnect();
// }
// }, GLOBAL.SERVERS.OPEN);
// testUtils.testWithClient('should be able to quit in PubSub mode', async client => { assert.equal(client.isOpen, false);
// await client.subscribe('channel', () => { }, GLOBAL.SERVERS.OPEN);
// // noop });
// });
// await assert.doesNotReject(client.quit()); testUtils.testWithClient('ConnectionTimeoutError', async client => {
const promise = assert.rejects(client.connect(), ConnectionTimeoutError),
start = process.hrtime.bigint();
// assert.equal(client.isOpen, false); while (process.hrtime.bigint() - start < 1_000_000) {
// }, GLOBAL.SERVERS.OPEN); // block the event loop for 1ms, to make sure the connection will timeout
// }); }
// testUtils.testWithClient('ConnectionTimeoutError', async client => { await promise;
// const promise = assert.rejects(client.connect(), ConnectionTimeoutError), }, {
// start = process.hrtime.bigint(); ...GLOBAL.SERVERS.OPEN,
clientOptions: {
socket: {
connectTimeout: 1
}
},
disableClientSetup: true
});
// while (process.hrtime.bigint() - start < 1_000_000) { testUtils.testWithClient('client.quit', async client => {
// // block the event loop for 1ms, to make sure the connection will timeout await client.connect();
// }
// await promise; const pingPromise = client.ping(),
// }, { quitPromise = client.quit();
// ...GLOBAL.SERVERS.OPEN, assert.equal(client.isOpen, false);
// clientOptions: {
// socket: {
// connectTimeout: 1
// }
// },
// disableClientSetup: true
// });
// testUtils.testWithClient('client.quit', async client => { const [ping, quit] = await Promise.all([
// await client.connect(); pingPromise,
quitPromise,
assert.rejects(client.ping(), ClientClosedError)
]);
// const pingPromise = client.ping(), assert.equal(ping, 'PONG');
// quitPromise = client.quit(); assert.equal(quit, 'OK');
// assert.equal(client.isOpen, false); }, {
...GLOBAL.SERVERS.OPEN,
disableClientSetup: true
});
// const [ping, quit] = await Promise.all([ testUtils.testWithClient('client.disconnect', async client => {
// pingPromise, const pingPromise = client.ping(),
// quitPromise, disconnectPromise = client.disconnect();
// assert.rejects(client.ping(), ClientClosedError) assert.equal(client.isOpen, false);
// ]); await Promise.all([
assert.rejects(pingPromise, DisconnectsClientError),
assert.doesNotReject(disconnectPromise),
assert.rejects(client.ping(), ClientClosedError)
]);
}, GLOBAL.SERVERS.OPEN);
// assert.equal(ping, 'PONG'); testUtils.testWithClient('should be able to connect after disconnect (see #1801)', async client => {
// assert.equal(quit, 'OK'); await client.disconnect();
// }, { await client.connect();
// ...GLOBAL.SERVERS.OPEN, }, GLOBAL.SERVERS.OPEN);
// disableClientSetup: true
// });
// testUtils.testWithClient('client.disconnect', async client => { testUtils.testWithClient('should be able to use ref and unref', client => {
// const pingPromise = client.ping(), client.unref();
// disconnectPromise = client.disconnect(); client.ref();
// assert.equal(client.isOpen, false); }, GLOBAL.SERVERS.OPEN);
// await Promise.all([
// assert.rejects(pingPromise, DisconnectsClientError),
// assert.doesNotReject(disconnectPromise),
// assert.rejects(client.ping(), ClientClosedError)
// ]);
// }, GLOBAL.SERVERS.OPEN);
// testUtils.testWithClient('should be able to connect after disconnect (see #1801)', async client => { testUtils.testWithClient('pingInterval', async client => {
// await client.disconnect(); assert.deepEqual(
// await client.connect(); await once(client, 'ping-interval'),
// }, GLOBAL.SERVERS.OPEN); ['PONG']
);
}, {
...GLOBAL.SERVERS.OPEN,
clientOptions: {
pingInterval: 1
}
});
// testUtils.testWithClient('should be able to use ref and unref', client => { testUtils.testWithClient('should reject commands in connect phase when `disableOfflineQueue`', async client => {
// client.unref(); const connectPromise = client.connect();
// client.ref(); await assert.rejects(
// }, GLOBAL.SERVERS.OPEN); client.ping(),
ClientOfflineError
// testUtils.testWithClient('pingInterval', async client => { );
// assert.deepEqual( await connectPromise;
// await once(client, 'ping-interval'), await client.disconnect();
// ['PONG'] }, {
// ); ...GLOBAL.SERVERS.OPEN,
// }, { clientOptions: {
// ...GLOBAL.SERVERS.OPEN, disableOfflineQueue: true
// clientOptions: { },
// pingInterval: 1 disableClientSetup: true
// } });
// });
// testUtils.testWithClient('should reject commands in connect phase when `disableOfflineQueue`', async client => {
// const connectPromise = client.connect();
// await assert.rejects(
// client.ping(),
// ClientOfflineError
// );
// await connectPromise;
// await client.disconnect();
// }, {
// ...GLOBAL.SERVERS.OPEN,
// clientOptions: {
// disableOfflineQueue: true
// },
// disableClientSetup: true
// });
describe('MONITOR', () => { describe('MONITOR', () => {
testUtils.testWithClient('should be able to monitor commands', async client => { testUtils.testWithClient('should be able to monitor commands', async client => {

View File

@@ -59,6 +59,12 @@ export class DoublyLinkedList<T> {
}; };
} }
add(value: T, prepend = false) {
return prepend ?
this.unshift(value) :
this.push(value);
}
shift() { shift() {
if (this._head === undefined) return undefined; if (this._head === undefined) return undefined;