Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
166 changes: 103 additions & 63 deletions storage/redis/README.md

Large diffs are not rendered by default.

77 changes: 30 additions & 47 deletions storage/redis/src/create.ts
Original file line number Diff line number Diff line change
@@ -1,67 +1,50 @@
import type { RedisClientOptions, RedisClientType } from "@redis/client";
import type { RedisClientType } from "@redis/client";
import { Keyv, type KeyvAny } from "keyv";
import KeyvRedis from "./index.js";
import type { KeyvRedisOptions } from "./types.js";
import type { KeyvRedisConnect, KeyvRedisOptions } from "./types.js";

/**
* Will create a Keyv instance with the Redis adapter. This will also set the namespace and disable the Keyv
* key prefix to avoid double prefixing of keys.
* @param {string | RedisClientOptions | RedisClientType} [connect] - How to connect to the Redis server. If string pass in the url, if object pass in the options, if RedisClient pass in the client. If nothing is passed in, it will default to 'redis://localhost:6379'.
* @param {KeyvRedisOptions} [options] - Options for the adapter such as namespace, keyPrefixSeparator, and clearBatchSize.
* @returns {Keyv} - Keyv instance with the Redis adapter
* Create a Keyv instance backed by {@link KeyvRedis}. Namespace is applied on both
* Keyv and the adapter so keys are prefixed once (`namespace::key` with the default separator).
*
* @param {KeyvRedisConnect} [connect] - URI, client/cluster/sentinel options, or an existing
* connection. Defaults to `"redis://localhost:6379"`.
* @param {KeyvRedisOptions} [options] - Adapter options such as `namespace`, `keyPrefixSeparator`,
* `clearBatchSize`, `throwOnErrors`, and `connectionTimeout`.
* @returns {Keyv} A Keyv instance using KeyvRedis as the store.
* @example
* ```ts
* const keyv = createKeyv("redis://localhost:6379", { namespace: "cache" });
* ```
*/
export function createKeyv(
connect?: string | RedisClientOptions | RedisClientType,
options?: KeyvRedisOptions,
): Keyv {
export function createKeyv(connect?: KeyvRedisConnect, options?: KeyvRedisOptions): Keyv {
connect ??= "redis://localhost:6379";
const adapter = new KeyvRedis(connect, options);
const keyv = new Keyv({
store: adapter,
namespace: adapter.namespace,
});

if (options?.namespace) {
adapter.namespace = options.namespace;
const keyv = new Keyv(adapter, {
namespace: options?.namespace,
});

if (options?.throwOnConnectError) {
// Set the throwOnError in Keyv so it throws
keyv.throwOnErrors = true;
}

if (options?.throwOnErrors) {
// Set the throwOnError in Keyv so it throws
keyv.throwOnErrors = true;
}

return keyv;
}

const keyv = new Keyv(adapter);

if (options?.throwOnConnectError) {
// Set the throwOnError in Keyv so it throws
keyv.throwOnErrors = true;
}

if (options?.throwOnErrors) {
// Set the throwOnError in Keyv so it throws
if (options?.throwOnConnectError || options?.throwOnErrors) {
keyv.throwOnErrors = true;
}

keyv.namespace = undefined; // Ensure no namespace is set
return keyv;
}

/**
* Will create a non-blocking Keyv instance with the Redis adapter. This does everything `createKeyv` does but also
* disables throwing errors, removes the offline queue, and disables the reconnect strategy so that when used as a
* secondary cache (such as with cacheable) it does not block the primary cache on connection errors or timeouts.
* @param {string | RedisClientOptions | RedisClientType} [connect] - How to connect to the Redis server. If string pass in the url, if object pass in the options, if RedisClient pass in the client. If nothing is passed in, it will default to 'redis://localhost:6379'.
* @param {KeyvRedisOptions} [options] - Options for the adapter such as namespace, keyPrefixSeparator, and clearBatchSize.
* @returns {Keyv} - non-blocking Keyv instance with the Redis adapter
* Create a non-blocking Keyv instance with the Redis adapter. Same as {@link createKeyv}, then
* disables throwing, the Redis offline queue, and reconnect so a secondary cache (for example
* cacheable) does not block the primary cache on connection errors or timeouts.
*
* @param {KeyvRedisConnect} [connect] - URI, client/cluster/sentinel options, or an existing
* connection. Defaults to `"redis://localhost:6379"`.
* @param {KeyvRedisOptions} [options] - Adapter options. `throwOnConnectError` and `throwOnErrors`
* are forced off on the returned instance.
* @returns {Keyv} A non-blocking Keyv instance using KeyvRedis as the store.
*/
export function createKeyvNonBlocking(
connect?: string | RedisClientOptions | RedisClientType,
connect?: KeyvRedisConnect,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Disable retries on cluster and sentinel clients too

Expanding createKeyvNonBlocking to accept KeyvRedisConnect advertises cluster and sentinel support, but the implementation still casts every connection to RedisClientType and mutates standalone-only options.disableOfflineQueue and options.socket. Cluster and sentinel node settings live in their respective nested client defaults, so these assignments do not disable their offline queues or reconnect strategies; when Redis is unavailable, the supposedly non-blocking secondary cache can therefore continue queueing or retrying and delay requests.

Useful? React with 👍 / 👎.

options?: KeyvRedisOptions,
): Keyv {
const keyv = createKeyv(connect, options);
Expand Down
Loading