Skip to content

Commit c3124c5

Browse files
uglidedwdougherty
andauthored
Add Production usage docs for Node-Redis (#2696)
* Add Production usage docs for Node-Redis * Update docs/connect/clients/nodejs.md Co-authored-by: David Dougherty <[email protected]> * Update docs/connect/clients/nodejs.md Co-authored-by: David Dougherty <[email protected]> * Update docs/connect/clients/nodejs.md Co-authored-by: David Dougherty <[email protected]> * Update docs/connect/clients/nodejs.md Co-authored-by: David Dougherty <[email protected]> * Update docs/connect/clients/nodejs.md Co-authored-by: David Dougherty <[email protected]> * Update docs/connect/clients/nodejs.md Co-authored-by: David Dougherty <[email protected]> * Address review suggestions --------- Co-authored-by: David Dougherty <[email protected]>
1 parent 02d8fcd commit c3124c5

File tree

1 file changed

+50
-139
lines changed

1 file changed

+50
-139
lines changed

docs/connect/clients/nodejs.md

+50-139
Original file line numberDiff line numberDiff line change
@@ -136,166 +136,77 @@ await client.disconnect();
136136

137137
You can also use discrete parameters and UNIX sockets. Details can be found in the [client configuration guide](https://github.com/redis/node-redis/blob/master/docs/client-configuration.md).
138138

139-
### Example: Indexing and querying JSON documents
139+
### Production usage
140140

141-
Make sure that you have Redis Stack and `node-redis` installed. Import dependencies:
141+
#### Handling errors
142+
Node-Redis provides [multiple events to handle various scenarios](https://github.com/redis/node-redis?tab=readme-ov-file#events), among which the most critical is the `error` event.
142143

143-
```js
144-
import {AggregateSteps, AggregateGroupByReducers, createClient, SchemaFieldTypes} from 'redis';
145-
const client = createClient();
146-
await client.connect();
147-
```
144+
This event is triggered whenever an error occurs within the client.
148145

149-
Create an index.
146+
It is crucial to listen for error events.
150147

151-
```js
152-
try {
153-
await client.ft.create('idx:users', {
154-
'$.name': {
155-
type: SchemaFieldTypes.TEXT,
156-
SORTABLE: true
157-
},
158-
'$.city': {
159-
type: SchemaFieldTypes.TEXT,
160-
AS: 'city'
161-
},
162-
'$.age': {
163-
type: SchemaFieldTypes.NUMERIC,
164-
AS: 'age'
165-
}
166-
}, {
167-
ON: 'JSON',
168-
PREFIX: 'user:'
169-
});
170-
} catch (e) {
171-
if (e.message === 'Index already exists') {
172-
console.log('Index exists already, skipped creation.');
173-
} else {
174-
// Something went wrong, perhaps RediSearch isn't installed...
175-
console.error(e);
176-
process.exit(1);
177-
}
178-
}
179-
```
180148

181-
Create JSON documents to add to your database.
149+
If a client does not register at least one error listener and an error occurs, the system will throw that error, potentially causing the Node.js process to exit unexpectedly.
150+
See [the EventEmitter docs](https://nodejs.org/api/events.html#events_error_events) for more details.
182151

183-
```js
184-
await Promise.all([
185-
client.json.set('user:1', '$', {
186-
"name": "Paul John",
187-
"email": "[email protected]",
188-
"age": 42,
189-
"city": "London"
190-
}),
191-
client.json.set('user:2', '$', {
192-
"name": "Eden Zamir",
193-
"email": "[email protected]",
194-
"age": 29,
195-
"city": "Tel Aviv"
196-
}),
197-
client.json.set('user:3', '$', {
198-
"name": "Paul Zamir",
199-
"email": "[email protected]",
200-
"age": 35,
201-
"city": "Tel Aviv"
202-
}),
203-
]);
152+
```typescript
153+
const client = createClient({
154+
// ... client options
155+
});
156+
// Always ensure there's a listener for errors in the client to prevent process crashes due to unhandled errors
157+
client.on('error', error => {
158+
console.error(`Redis client error:`, error);
159+
});
204160
```
205161

206-
Let's find user 'Paul` and filter the results by age.
207162

208-
```js
209-
let result = await client.ft.search(
210-
'idx:users',
211-
'Paul @age:[30 40]'
212-
);
213-
console.log(JSON.stringify(result, null, 2));
214-
/*
215-
{
216-
"total": 1,
217-
"documents": [
218-
{
219-
"id": "user:3",
220-
"value": {
221-
"name": "Paul Zamir",
222-
"email": "[email protected]",
223-
"age": 35,
224-
"city": "Tel Aviv"
225-
}
226-
}
227-
]
228-
}
229-
*/
230-
```
163+
#### Handling reconnections
231164

232-
Return only the city field.
165+
If network issues or other problems unexpectedly close the socket, the client will reject all commands already sent, since the server might have already executed them.
166+
The rest of the pending commands will remain queued in memory until a new socket is established.
167+
This behaviour is controlled by the `enableOfflineQueue` option, which is enabled by default.
233168

234-
```js
235-
result = await client.ft.search(
236-
'idx:users',
237-
'Paul @age:[30 40]',
238-
{
239-
RETURN: ['$.city']
240-
}
241-
);
242-
console.log(JSON.stringify(result, null, 2));
169+
The client uses `reconnectStrategy` to decide when to attempt to reconnect.
170+
The default strategy is to calculate the delay before each attempt based on the attempt number `Math.min(retries * 50, 500)`. You can customize this strategy by passing a supported value to `reconnectStrategy` option:
243171

244-
/*
245-
{
246-
"total": 1,
247-
"documents": [
248-
{
249-
"id": "user:3",
250-
"value": {
251-
"$.city": "Tel Aviv"
252-
}
172+
173+
1. Define a callback `(retries: number, cause: Error) => false | number | Error` **(recommended)**
174+
```typescript
175+
const client = createClient({
176+
socket: {
177+
reconnectStrategy: function(retries) {
178+
if (retries > 20) {
179+
console.log("Too many attempts to reconnect. Redis connection was terminated");
180+
return new Error("Too many retries.");
181+
} else {
182+
return retries * 500;
183+
}
253184
}
254-
]
255-
}
256-
*/
185+
}
186+
});
187+
client.on('error', error => console.error('Redis client error:', error));
257188
```
258-
259-
Count all users in the same city.
189+
In the provided reconnection strategy callback, the client attempts to reconnect up to 20 times with a delay of `retries * 500` milliseconds between attempts.
190+
After approximately two minutes, the client logs an error message and terminates the connection if the maximum retry limit is exceeded.
260191

261-
```js
262-
result = await client.ft.aggregate('idx:users', '*', {
263-
STEPS: [
264-
{
265-
type: AggregateSteps.GROUPBY,
266-
properties: ['@city'],
267-
REDUCE: [
268-
{
269-
type: AggregateGroupByReducers.COUNT,
270-
AS: 'count'
271-
}
272-
]
273-
}
274-
]
275-
})
276-
console.log(JSON.stringify(result, null, 2));
277192

278-
/*
279-
{
280-
"total": 2,
281-
"results": [
282-
{
283-
"city": "London",
284-
"count": "1"
285-
},
286-
{
287-
"city": "Tel Aviv",
288-
"count": "2"
289-
}
290-
]
291-
}
292-
*/
193+
2. Use a numerical value to set a fixed delay in milliseconds.
194+
3. Use `false` to disable reconnection attempts. This option should only be used for testing purposes.
195+
196+
#### Timeout
293197

294-
await client.quit();
198+
To set a timeout for a connection, use the `connectTimeout` option:
199+
```typescript
200+
const client = createClient({
201+
// setting a 10-second timeout
202+
connectTimeout: 10000 // in milliseconds
203+
});
204+
client.on('error', error => console.error('Redis client error:', error));
295205
```
296206

297207
### Learn more
298208

209+
* [Node-Redis Configuration Options](https://github.com/redis/node-redis/blob/master/docs/client-configuration.md)
299210
* [Redis commands](https://redis.js.org/#node-redis-usage-redis-commands)
300211
* [Programmability](https://redis.js.org/#node-redis-usage-programmability)
301212
* [Clustering](https://redis.js.org/#node-redis-usage-clustering)

0 commit comments

Comments
 (0)