Skip to content

Commit

Permalink
Ping interval (#2321)
Browse files Browse the repository at this point in the history
* fix #1598 fix #2276 - add `pingInterval` to client config

* setPingTimer on ready (instead of on connect)

* use isReady (instead of isOpen) and fix test

* Update client-configuration.md
  • Loading branch information
leibale authored Nov 10, 2022
1 parent e0e96ae commit 3c2f7ab
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/client-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
| readonly | `false` | Connect in [`READONLY`](https://redis.io/commands/readonly) mode |
| legacyMode | `false` | Maintain some backwards compatibility (see the [Migration Guide](./v3-to-v4.md)) |
| isolationPoolOptions | | See the [Isolated Execution Guide](./isolated-execution.md) |
| pingInterval | | Send `PING` command at interval (in ms). Useful with "[Azure Cache for Redis](https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-best-practices-connection#idle-timeout)" |

## Reconnect Strategy

Expand Down
12 changes: 12 additions & 0 deletions packages/client/lib/client/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -862,4 +862,16 @@ describe('Client', () => {
client.unref();
client.ref();
}, GLOBAL.SERVERS.OPEN);

testUtils.testWithClient('pingInterval', async client => {
assert.deepEqual(
await once(client, 'ping-interval'),
['PONG']
);
}, {
...GLOBAL.SERVERS.OPEN,
clientOptions: {
pingInterval: 1
}
});
});
22 changes: 21 additions & 1 deletion packages/client/lib/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export interface RedisClientOptions<
readonly?: boolean;
legacyMode?: boolean;
isolationPoolOptions?: PoolOptions;
pingInterval?: number;
}

type WithCommands = {
Expand Down Expand Up @@ -281,9 +282,12 @@ export default class RedisClient<
this.#queue.flushAll(err);
}
})
.on('connect', () => this.emit('connect'))
.on('connect', () => {
this.emit('connect');
})
.on('ready', () => {
this.emit('ready');
this.#setPingTimer();
this.#tick();
})
.on('reconnecting', () => this.emit('reconnecting'))
Expand Down Expand Up @@ -348,6 +352,22 @@ export default class RedisClient<
(...args: Array<unknown>): void => (this as any).sendCommand(name, ...args);
}

#pingTimer?: NodeJS.Timer;

#setPingTimer(): void {
if (!this.#options?.pingInterval || !this.#socket.isReady) return;
clearTimeout(this.#pingTimer);

this.#pingTimer = setTimeout(() => {
if (!this.#socket.isReady) return;

(this as unknown as RedisClientType<M, F, S>).ping()
.then(reply => this.emit('ping-interval', reply))
.catch(err => this.emit('error', err))
.finally(() => this.#setPingTimer());
}, this.#options.pingInterval);
}

duplicate(overrides?: Partial<RedisClientOptions<M, F, S>>): RedisClientType<M, F, S> {
return new (Object.getPrototypeOf(this).constructor)({
...this.#options,
Expand Down

0 comments on commit 3c2f7ab

Please sign in to comment.