You've already forked node-redis
mirror of
https://github.com/redis/node-redis.git
synced 2025-08-07 13:22:56 +03:00
Update doctest client with latest v4 release (#2844)
This commit is contained in:
@@ -10,7 +10,7 @@ If don't want to queue commands in memory until a new socket is established, set
|
||||
|
||||
## How are commands batched?
|
||||
|
||||
Commands are pipelined using [`queueMicrotask`](https://nodejs.org/api/globals.html#globals_queuemicrotask_callback).
|
||||
Commands are pipelined using [`setImmediate`](https://nodejs.org/api/timers.html#setimmediatecallback-args).
|
||||
|
||||
If `socket.write()` returns `false`—meaning that ["all or part of the data was queued in user memory"](https://nodejs.org/api/net.html#net_socket_write_data_encoding_callback:~:text=all%20or%20part%20of%20the%20data%20was%20queued%20in%20user%20memory)—the commands will stack in memory until the [`drain`](https://nodejs.org/api/net.html#net_event_drain) event is fired.
|
||||
|
||||
|
@@ -15,7 +15,7 @@
|
||||
| socket.reconnectStrategy | `retries => Math.min(retries * 50, 500)` | A function containing the [Reconnect Strategy](#reconnect-strategy) logic |
|
||||
| username | | ACL username ([see ACL guide](https://redis.io/topics/acl)) |
|
||||
| password | | ACL password or the old "--requirepass" password |
|
||||
| name | | Connection name ([see `CLIENT SETNAME`](https://redis.io/commands/client-setname)) |
|
||||
| name | | Client name ([see `CLIENT SETNAME`](https://redis.io/commands/client-setname)) |
|
||||
| database | | Redis database number (see [`SELECT`](https://redis.io/commands/select) command) |
|
||||
| modules | | Included [Redis Modules](../README.md#packages) |
|
||||
| scripts | | Script definitions (see [Lua Scripts](../README.md#lua-scripts)) |
|
||||
@@ -25,16 +25,24 @@
|
||||
| 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)" |
|
||||
| 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
|
||||
|
||||
You can implement a custom reconnect strategy as a function:
|
||||
When the socket closes unexpectedly (without calling `.quit()`/`.disconnect()`), the client uses `reconnectStrategy` to decide what to do. The following values are supported:
|
||||
1. `false` -> do not reconnect, close the client and flush the command queue.
|
||||
2. `number` -> wait for `X` milliseconds before reconnecting.
|
||||
3. `(retries: number, cause: Error) => false | number | Error` -> `number` is the same as configuring a `number` directly, `Error` is the same as `false`, but with a custom error.
|
||||
|
||||
- Receives the number of retries attempted so far.
|
||||
- Returns `number | Error`:
|
||||
- `number`: wait time in milliseconds prior to attempting a reconnect.
|
||||
- `Error`: closes the client and flushes internal command queues.
|
||||
By default the strategy is `Math.min(retries * 50, 500)`, but it can be overwritten like so:
|
||||
|
||||
```javascript
|
||||
createClient({
|
||||
socket: {
|
||||
reconnectStrategy: retries => Math.min(retries * 50, 1000)
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## TLS
|
||||
|
||||
@@ -44,7 +52,7 @@ To enable TLS, set `socket.tls` to `true`. Below are some basic examples.
|
||||
|
||||
### Create a SSL client
|
||||
|
||||
```typescript
|
||||
```javascript
|
||||
createClient({
|
||||
socket: {
|
||||
tls: true,
|
||||
@@ -56,7 +64,7 @@ createClient({
|
||||
|
||||
### Create a SSL client using a self-signed certificate
|
||||
|
||||
```typescript
|
||||
```javascript
|
||||
createClient({
|
||||
socket: {
|
||||
tls: true,
|
||||
|
@@ -35,35 +35,70 @@ const value = await cluster.get('key');
|
||||
| rootNodes | | An array of root nodes that are part of the cluster, which will be used to get the cluster topology. Each element in the array is a client configuration object. There is no need to specify every node in the cluster, 3 should be enough to reliably connect and obtain the cluster configuration from the server |
|
||||
| defaults | | The default configuration values for every client in the cluster. Use this for example when specifying an ACL user to connect with |
|
||||
| useReplicas | `false` | When `true`, distribute load by executing readonly commands (such as `GET`, `GEOSEARCH`, etc.) across all cluster nodes. When `false`, only use master nodes |
|
||||
| minimizeConnections | `false` | When `true`, `.connect()` will only discover the cluster topology, without actually connecting to all the nodes. Useful for short-term or Pub/Sub-only connections. |
|
||||
| maxCommandRedirections | `16` | The maximum number of times a command will be redirected due to `MOVED` or `ASK` errors |
|
||||
| nodeAddressMap | | Defines the [node address mapping](#node-address-map) |
|
||||
| modules | | Included [Redis Modules](../README.md#packages) |
|
||||
| scripts | | Script definitions (see [Lua Scripts](../README.md#lua-scripts)) |
|
||||
| functions | | Function definitions (see [Functions](../README.md#functions)) |
|
||||
## Auth with password and username
|
||||
|
||||
## Node Address Map
|
||||
|
||||
A node address map is required when a Redis cluster is configured with addresses that are inaccessible by the machine running the Redis client.
|
||||
This is a mapping of addresses and ports, with the values being the accessible address/port combination. Example:
|
||||
|
||||
Specifying the password in the URL or a root node will only affect the connection to that specific node. In case you want to set the password for all the connections being created from a cluster instance, use the `defaults` option.
|
||||
```javascript
|
||||
createCluster({
|
||||
rootNodes: [{
|
||||
url: 'external-host-1.io:30001'
|
||||
url: 'redis://10.0.0.1:30001'
|
||||
}, {
|
||||
url: 'external-host-2.io:30002'
|
||||
url: 'redis://10.0.0.2:30002'
|
||||
}],
|
||||
defaults: {
|
||||
username: 'username',
|
||||
password: 'password'
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## Node Address Map
|
||||
|
||||
A mapping between the addresses in the cluster (see `CLUSTER SHARDS`) and the addresses the client should connect to.
|
||||
Useful when the cluster is running on a different network to the client.
|
||||
|
||||
```javascript
|
||||
const rootNodes = [{
|
||||
url: 'external-host-1.io:30001'
|
||||
}, {
|
||||
url: 'external-host-2.io:30002'
|
||||
}];
|
||||
|
||||
// Use either a static mapping:
|
||||
createCluster({
|
||||
rootNodes,
|
||||
nodeAddressMap: {
|
||||
'10.0.0.1:30001': {
|
||||
host: 'external-host-1.io',
|
||||
host: 'external-host.io',
|
||||
port: 30001
|
||||
},
|
||||
'10.0.0.2:30002': {
|
||||
host: 'external-host-2.io',
|
||||
host: 'external-host.io',
|
||||
port: 30002
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// or create the mapping dynamically, as a function:
|
||||
createCluster({
|
||||
rootNodes,
|
||||
nodeAddressMap(address) {
|
||||
const indexOfDash = address.lastIndexOf('-'),
|
||||
indexOfDot = address.indexOf('.', indexOfDash),
|
||||
indexOfColons = address.indexOf(':', indexOfDot);
|
||||
|
||||
return {
|
||||
host: `external-host-${address.substring(indexOfDash + 1, indexOfDot)}.io`,
|
||||
port: Number(address.substring(indexOfColons + 1))
|
||||
};
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
> This is a common problem when using ElastiCache. See [Accessing ElastiCache from outside AWS](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/accessing-elasticache.html) for more information on that.
|
||||
|
88
docs/pub-sub.md
Normal file
88
docs/pub-sub.md
Normal file
@@ -0,0 +1,88 @@
|
||||
# Pub/Sub
|
||||
|
||||
The Pub/Sub API is implemented by `RedisClient` and `RedisCluster`.
|
||||
|
||||
## Pub/Sub with `RedisClient`
|
||||
|
||||
Pub/Sub requires a dedicated stand-alone client. You can easily get one by `.duplicate()`ing an existing `RedisClient`:
|
||||
|
||||
```typescript
|
||||
const subscriber = client.duplicate();
|
||||
subscriber.on('error', err => console.error(err));
|
||||
await subscriber.connect();
|
||||
```
|
||||
|
||||
When working with a `RedisCluster`, this is handled automatically for you.
|
||||
|
||||
### `sharded-channel-moved` event
|
||||
|
||||
`RedisClient` emits the `sharded-channel-moved` event when the ["cluster slot"](https://redis.io/docs/reference/cluster-spec/#key-distribution-model) of a subscribed [Sharded Pub/Sub](https://redis.io/docs/manual/pubsub/#sharded-pubsub) channel has been moved to another shard.
|
||||
|
||||
The event listener signature is as follows:
|
||||
```typescript
|
||||
(
|
||||
channel: string,
|
||||
listeners: {
|
||||
buffers: Set<Listener>;
|
||||
strings: Set<Listener>;
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Subscribing
|
||||
|
||||
```javascript
|
||||
const listener = (message, channel) => console.log(message, channel);
|
||||
await client.subscribe('channel', listener);
|
||||
await client.pSubscribe('channe*', listener);
|
||||
// Use sSubscribe for sharded Pub/Sub:
|
||||
await client.sSubscribe('channel', listener);
|
||||
```
|
||||
|
||||
> ⚠️ Subscribing to the same channel more than once will create multiple listeners which will each be called when a message is recieved.
|
||||
|
||||
## Publishing
|
||||
|
||||
```javascript
|
||||
await client.publish('channel', 'message');
|
||||
// Use sPublish for sharded Pub/Sub:
|
||||
await client.sPublish('channel', 'message');
|
||||
```
|
||||
|
||||
## Unsubscribing
|
||||
|
||||
The code below unsubscribes all listeners from all channels.
|
||||
|
||||
```javascript
|
||||
await client.unsubscribe();
|
||||
await client.pUnsubscribe();
|
||||
// Use sUnsubscribe for sharded Pub/Sub:
|
||||
await client.sUnsubscribe();
|
||||
```
|
||||
|
||||
To unsubscribe from specific channels:
|
||||
|
||||
```javascript
|
||||
await client.unsubscribe('channel');
|
||||
await client.unsubscribe(['1', '2']);
|
||||
```
|
||||
|
||||
To unsubscribe a specific listener:
|
||||
|
||||
```javascript
|
||||
await client.unsubscribe('channel', listener);
|
||||
```
|
||||
|
||||
## Buffers
|
||||
|
||||
Publishing and subscribing using `Buffer`s is also supported:
|
||||
|
||||
```javascript
|
||||
await subscriber.subscribe('channel', message => {
|
||||
console.log(message); // <Buffer 6d 65 73 73 61 67 65>
|
||||
}, true); // true = subscribe in `Buffer` mode.
|
||||
|
||||
await subscriber.publish(Buffer.from('channel'), Buffer.from('message'));
|
||||
```
|
||||
|
||||
> NOTE: Buffers and strings are supported both for the channel name and the message. You can mix and match these as desired.
|
Reference in New Issue
Block a user