Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exploration of Client Side Caching support #2694

Draft
wants to merge 3 commits into
base: v5
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions packages/client/lib/RESP/types.ts
Expand Up @@ -263,7 +263,13 @@ export type CommandArguments = Array<RedisArgument> & { preserve?: unknown };
// response?: ResponsePolicies | null;
// };

export interface CacheInfo {
cacheKey: string;
redisKeys: Array<string>
}

export type Command = {
name?: () => string;
FIRST_KEY_INDEX?: number | ((this: void, ...args: Array<any>) => RedisArgument | undefined);
IS_READ_ONLY?: boolean;
/**
Expand All @@ -275,6 +281,7 @@ export type Command = {
transformArguments(this: void, ...args: Array<any>): CommandArguments;
TRANSFORM_LEGACY_REPLY?: boolean;
transformReply: TransformReply | Record<RespVersions, TransformReply>;
getCacheInfo?: (...args: Array<any>) => CacheInfo | undefined;
};

export type RedisCommands = Record<string, Command>;
Expand Down
64 changes: 64 additions & 0 deletions packages/client/lib/client/README-cache.md
@@ -0,0 +1,64 @@
# Client Side Caching Support

Client Side Caching enables Redis Servers and Clients to work together to enable a client to cache results from command sent to a server and be informed by the server when the cached result is no longer valid.

## Usage

node-redis supports two ways of instantiating client side caching support

Note: Client Side Caching is only supported with RESP3.

### Anonymous Cache

```javascript
const client = createClient({RESP: 3, clientSideCache: {ttl: 0, maxEntries: 0, lru: false}})
```

In this instance, the cache is opaque to the user, and they have no control over it.

### Controllable Cache

```javascript
const ttl = 0, maxEntries = 0, lru = false;
const cache = new BasicClientSideCache(ttl, maxEntries, lru);
const client = createClient({RESP: 3, clientSideCache: cache});
```

In this instance, the user has full control over the cache, as they have access to the cache object.

They can manually invalidate keys

```javascript
cache.invalidate(key);
```

they can clear the entire cache
g
```javascript
cache.clear();
```

as well as get cache metrics

```typescript
const hits: number = cache.cacheHits();
const misses: number = cache.cacheMisses();
```

## Pooled Caching

Similar to individual clients, node-redis also supports caching for its pooled client object, with the cache being able to be instantiated in an anonymous manner or a controllable manner.

### Anonymous Cache

```javascript
const client = createClientPool({RESP: 3}, {clientSideCache: {ttl: 0, maxEntries: 0, lru: false}, minimum: 8});
```

### Controllable Cache

```javascript
const ttl = 0, maxEntries = 0, lru = false;
const cache = new BasicPooledClientSideCache(ttl, maxEntries, lru);
const client = createClientPool({RESP: 3}, {clientSideCache: cache, minimum: 8});
```