Skip to content

Commit 5b63382

Browse files
sastcsghnkaradzhov
andauthored
feat(client): Emit invalidate events from client (#3076)
* add emitInvalidate option * Add documentation for event * Re-write emitInvalidate logic * Fix issues after merge --------- Co-authored-by: Nikolay Karadzhov <[email protected]>
1 parent 8a1b4b4 commit 5b63382

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ The Node Redis client class is an Nodejs EventEmitter and it emits an event each
293293
| `error` | An error has occurred—usually a network issue such as "Socket closed unexpectedly" | `(error: Error)` |
294294
| `reconnecting` | Client is trying to reconnect to the server | _No arguments_ |
295295
| `sharded-channel-moved` | See [here](https://github.com/redis/node-redis/blob/master/docs/pub-sub.md#sharded-channel-moved-event) | See [here](https://github.com/redis/node-redis/blob/master/docs/pub-sub.md#sharded-channel-moved-event) |
296+
| `invalidate` | Client Tracking is on with `emitInvalidate` and a key is invalidated | `(key: RedisItem \| null)` |
296297

297298
> :warning: You **MUST** listen to `error` events. If a client doesn't have at least one `error` listener registered and
298299
> an `error` occurs, that error will be thrown and the Node.js process will exit. See the [ > `EventEmitter` docs](https://nodejs.org/api/events.html#events_error_events) for more details.

packages/client/lib/client/index.ts

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,11 @@ export interface RedisClientOptions<
145145
* Tag to append to library name that is sent to the Redis server
146146
*/
147147
clientInfoTag?: string;
148+
/**
149+
* When set to true, client tracking is turned on and the client emits `invalidate` events when it receives invalidation messages from the redis server.
150+
* Mutually exclusive with `clientSideCache` option.
151+
*/
152+
emitInvalidate?: boolean;
148153
/**
149154
* Controls how the client handles Redis Enterprise maintenance push notifications.
150155
*
@@ -525,6 +530,19 @@ export default class RedisClient<
525530
this.#clientSideCache?.invalidate(null)
526531
}
527532

533+
return true
534+
});
535+
} else if (options?.emitInvalidate) {
536+
this.#queue.addPushHandler((push: Array<any>): boolean => {
537+
if (push[0].toString() !== 'invalidate') return false;
538+
539+
if (push[1] !== null) {
540+
for (const key of push[1]) {
541+
this.emit('invalidate', key);
542+
}
543+
} else {
544+
this.emit('invalidate', null);
545+
}
528546
return true
529547
});
530548
}
@@ -534,11 +552,15 @@ export default class RedisClient<
534552
if (options?.clientSideCache && options?.RESP !== 3) {
535553
throw new Error('Client Side Caching is only supported with RESP3');
536554
}
537-
555+
if (options?.emitInvalidate && options?.RESP !== 3) {
556+
throw new Error('emitInvalidate is only supported with RESP3');
557+
}
558+
if (options?.clientSideCache && options?.emitInvalidate) {
559+
throw new Error('emitInvalidate is not supported (or necessary) when clientSideCache is enabled');
560+
}
538561
if (options?.maintNotifications && options?.maintNotifications !== 'disabled' && options?.RESP !== 3) {
539562
throw new Error('Graceful Maintenance is only supported with RESP3');
540563
}
541-
542564
}
543565

544566
#initiateOptions(options: RedisClientOptions<M, F, S, RESP, TYPE_MAPPING> = {}): RedisClientOptions<M, F, S, RESP, TYPE_MAPPING> {
@@ -743,12 +765,17 @@ export default class RedisClient<
743765
}
744766
});
745767
}
746-
768+
747769
if (this.#clientSideCache) {
748770
commands.push({cmd: this.#clientSideCache.trackingOn()});
749771
}
750772

773+
if (this.#options?.emitInvalidate) {
774+
commands.push({cmd: ['CLIENT', 'TRACKING', 'ON']});
775+
}
776+
751777
const maintenanceHandshakeCmd = await EnterpriseMaintenanceManager.getHandshakeCommand(this.#options);
778+
752779
if(maintenanceHandshakeCmd) {
753780
commands.push(maintenanceHandshakeCmd);
754781
};

0 commit comments

Comments
 (0)