Skip to content

Commit a4403c9

Browse files
committed
Update client-side cache and improve documentation
1 parent 3dcf682 commit a4403c9

File tree

8 files changed

+241
-72
lines changed

8 files changed

+241
-72
lines changed

README.md

+18
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,24 @@ of sending a `QUIT` command to the server, the client can simply close the netwo
235235
client.destroy();
236236
```
237237

238+
### Client Side Caching
239+
240+
Node Redis v5 adds support for [Client Side Caching](https://redis.io/docs/manual/client-side-caching/), which enables clients to cache query results locally. The Redis server will notify the client when cached results are no longer valid.
241+
242+
```typescript
243+
// Enable client side caching with RESP3
244+
const client = createClient({
245+
RESP: 3,
246+
clientSideCache: {
247+
ttl: 0, // Time-to-live (0 = no expiration)
248+
maxEntries: 0, // Maximum entries (0 = unlimited)
249+
evictPolicy: "LRU" // Eviction policy: "LRU" or "FIFO"
250+
}
251+
});
252+
```
253+
254+
See the [V5 documentation](./docs/v5.md#client-side-caching) for more details and advanced usage.
255+
238256
### Auto-Pipelining
239257

240258
Node Redis will automatically pipeline requests that are made during the same "tick".

docs/v5.md

+88
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,91 @@ await multi.exec(); // Array<ReplyUnion>
8989
await multi.exec<'typed'>(); // [string]
9090
await multi.execTyped(); // [string]
9191
```
92+
93+
# Client Side Caching
94+
95+
Node Redis v5 adds support for [Client Side Caching](https://redis.io/docs/manual/client-side-caching/), which enables clients to cache query results locally. The server will notify the client when cached results are no longer valid.
96+
97+
Client Side Caching is only supported with RESP3.
98+
99+
## Usage
100+
101+
There are two ways to implement client side caching:
102+
103+
### Anonymous Cache
104+
105+
```javascript
106+
const client = createClient({
107+
RESP: 3,
108+
clientSideCache: {
109+
ttl: 0, // Time-to-live in milliseconds (0 = no expiration)
110+
maxEntries: 0, // Maximum entries to store (0 = unlimited)
111+
evictPolicy: "LRU" // Eviction policy: "LRU" or "FIFO"
112+
}
113+
});
114+
```
115+
116+
In this instance, the cache is managed internally by the client.
117+
118+
### Controllable Cache
119+
120+
```javascript
121+
import { BasicClientSideCache } from 'redis';
122+
123+
const cache = new BasicClientSideCache({
124+
ttl: 0,
125+
maxEntries: 0,
126+
evictPolicy: "LRU"
127+
});
128+
129+
const client = createClient({
130+
RESP: 3,
131+
clientSideCache: cache
132+
});
133+
```
134+
135+
With this approach, you have direct access to the cache object for more control:
136+
137+
```javascript
138+
// Manually invalidate keys
139+
cache.invalidate(key);
140+
141+
// Clear the entire cache
142+
cache.clear();
143+
144+
// Get cache metrics
145+
const hits = cache.cacheHits();
146+
const misses = cache.cacheMisses();
147+
```
148+
149+
## Pooled Caching
150+
151+
Client side caching also works with client pools. For pooled clients, the cache is shared across all clients in the pool:
152+
153+
```javascript
154+
const client = createClientPool({RESP: 3}, {
155+
clientSideCache: {
156+
ttl: 0,
157+
maxEntries: 0,
158+
evictPolicy: "LRU"
159+
},
160+
minimum: 5
161+
});
162+
```
163+
164+
For a controllable pooled cache:
165+
166+
```javascript
167+
import { BasicPooledClientSideCache } from 'redis';
168+
169+
const cache = new BasicPooledClientSideCache({
170+
ttl: 0,
171+
maxEntries: 0,
172+
evictPolicy: "LRU"
173+
});
174+
175+
const client = createClientPool({RESP: 3}, {
176+
clientSideCache: cache,
177+
minimum: 5
178+
});
179+
```

package-lock.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/client/lib/client/README-cache.md

-64
This file was deleted.

packages/client/lib/client/cache.ts

+23-2
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,31 @@ type CmdFunc = () => Promise<ReplyUnion>;
88

99
type EvictionPolicy = "LRU" | "FIFO"
1010

11+
/**
12+
* Configuration options for Client Side Cache
13+
*/
1114
export interface ClientSideCacheConfig {
15+
/**
16+
* Time-to-live in milliseconds for cached entries.
17+
* Use 0 for no expiration.
18+
* @default 0
19+
*/
1220
ttl?: number;
21+
22+
/**
23+
* Maximum number of entries to store in the cache.
24+
* Use 0 for unlimited entries.
25+
* @default 0
26+
*/
1327
maxEntries?: number;
14-
evictPolocy?: EvictionPolicy;
28+
29+
/**
30+
* Eviction policy to use when the cache reaches its capacity.
31+
* - "LRU" (Least Recently Used): Evicts least recently accessed entries first
32+
* - "FIFO" (First In First Out): Evicts oldest entries first
33+
* @default "LRU"
34+
*/
35+
evictPolicy?: EvictionPolicy;
1536
}
1637

1738
type CacheCreator = {
@@ -109,7 +130,7 @@ export class BasicClientSideCache extends ClientSideCacheProvider {
109130
this.#keyToCacheKeySetMap = new Map<string, Set<string>>();
110131
this.ttl = config?.ttl ?? 0;
111132
this.maxEntries = config?.maxEntries ?? 0;
112-
this.lru = config?.evictPolocy !== "FIFO"
133+
this.lru = config?.evictPolicy !== "FIFO"
113134
}
114135

115136
/* logic of how caching works:

packages/client/lib/client/index.ts

+51-2
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,60 @@ export interface RedisClientOptions<
7878
*/
7979
pingInterval?: number;
8080
/**
81-
* TODO
81+
* Default command options to be applied to all commands executed through this client.
82+
*
83+
* These options can be overridden on a per-command basis when calling specific commands.
84+
*
85+
* @property {symbol} [chainId] - Identifier for chaining commands together
86+
* @property {boolean} [asap] - When true, the command is executed as soon as possible
87+
* @property {AbortSignal} [abortSignal] - AbortSignal to cancel the command
88+
* @property {TypeMapping} [typeMapping] - Custom type mappings between RESP and JavaScript types
89+
*
90+
* @example Setting default command options
91+
* ```
92+
* const client = createClient({
93+
* commandOptions: {
94+
* asap: true,
95+
* typeMapping: {
96+
* // Custom type mapping configuration
97+
* }
98+
* }
99+
* });
100+
* ```
82101
*/
83102
commandOptions?: CommandOptions<TYPE_MAPPING>;
84103
/**
85-
* TODO
104+
* Client Side Caching configuration.
105+
*
106+
* Enables Redis Servers and Clients to work together to cache results from commands
107+
* sent to a server. The server will notify the client when cached results are no longer valid.
108+
*
109+
* Note: Client Side Caching is only supported with RESP3.
110+
*
111+
* @example Anonymous cache configuration
112+
* ```
113+
* const client = createClient({
114+
* RESP: 3,
115+
* clientSideCache: {
116+
* ttl: 0,
117+
* maxEntries: 0,
118+
* evictPolicy: "LRU"
119+
* }
120+
* });
121+
* ```
122+
*
123+
* @example Using a controllable cache
124+
* ```
125+
* const cache = new BasicClientSideCache({
126+
* ttl: 0,
127+
* maxEntries: 0,
128+
* evictPolicy: "LRU"
129+
* });
130+
* const client = createClient({
131+
* RESP: 3,
132+
* clientSideCache: cache
133+
* });
134+
* ```
86135
*/
87136
clientSideCache?: ClientSideCacheProvider | ClientSideCacheConfig;
88137
}

packages/client/lib/client/pool.ts

+43-3
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,55 @@ export interface RedisPoolOptions {
2424
*/
2525
acquireTimeout: number;
2626
/**
27-
* TODO
27+
* The delay in milliseconds before a cleanup operation is performed on idle clients.
28+
*
29+
* After this delay, the pool will check if there are too many idle clients and destroy
30+
* excess ones to maintain optimal pool size.
2831
*/
2932
cleanupDelay: number;
3033
/**
31-
* TODO
34+
* Client Side Caching configuration for the pool.
35+
*
36+
* Enables Redis Servers and Clients to work together to cache results from commands
37+
* sent to a server. The server will notify the client when cached results are no longer valid.
38+
* In pooled mode, the cache is shared across all clients in the pool.
39+
*
40+
* Note: Client Side Caching is only supported with RESP3.
41+
*
42+
* @example Anonymous cache configuration
43+
* ```
44+
* const client = createClientPool({RESP: 3}, {
45+
* clientSideCache: {
46+
* ttl: 0,
47+
* maxEntries: 0,
48+
* evictPolicy: "LRU"
49+
* },
50+
* minimum: 5
51+
* });
52+
* ```
53+
*
54+
* @example Using a controllable cache
55+
* ```
56+
* const cache = new BasicPooledClientSideCache({
57+
* ttl: 0,
58+
* maxEntries: 0,
59+
* evictPolicy: "LRU"
60+
* });
61+
* const client = createClientPool({RESP: 3}, {
62+
* clientSideCache: cache,
63+
* minimum: 5
64+
* });
65+
* ```
3266
*/
3367
clientSideCache?: PooledClientSideCacheProvider | ClientSideCacheConfig;
3468
/**
35-
* TODO
69+
* Enable experimental support for RESP3 module commands.
70+
*
71+
* When enabled, allows the use of module commands that have been adapted
72+
* for the RESP3 protocol. This is an unstable feature and may change in
73+
* future versions.
74+
*
75+
* @default false
3676
*/
3777
unstableResp3Modules?: boolean;
3878
}

packages/redis/README.md

+17
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,23 @@ of sending a `QUIT` command to the server, the client can simply close the netwo
234234
```typescript
235235
client.destroy();
236236
```
237+
### Client Side Caching
238+
239+
Node Redis v5 adds support for [Client Side Caching](https://redis.io/docs/manual/client-side-caching/), which enables clients to cache query results locally. The Redis server will notify the client when cached results are no longer valid.
240+
241+
```typescript
242+
// Enable client side caching with RESP3
243+
const client = createClient({
244+
RESP: 3,
245+
clientSideCache: {
246+
ttl: 0, // Time-to-live (0 = no expiration)
247+
maxEntries: 0, // Maximum entries (0 = unlimited)
248+
evictPolicy: "LRU" // Eviction policy: "LRU" or "FIFO"
249+
}
250+
});
251+
```
252+
253+
See the [V5 documentation](../../docs/v5.md#client-side-caching) for more details and advanced usage.
237254

238255
### Auto-Pipelining
239256

0 commit comments

Comments
 (0)