You've already forked node-redis
mirror of
https://github.com/redis/node-redis.git
synced 2025-08-07 13:22:56 +03:00
V4 (#1624)
* init v4 * add .gitignore to benchmark * spawn redis-servers for tests, add some tests, fix client auth on connect * add tests coverage report * add tests workflow, replace nyc text reporter with text-summary * run tests with node 16.x & redis 6.x only (for now) * add socket events on client, stop reconnectiong when manually calling disconnect, remove abort signal listener when a command is written on the socket * add isOpen boolean getter on client, add maxLength option to command queue, add test for client.multi * move to use CommonJS * add MULTI and EXEC commands to when executing multi command, make client.multi return type innerit the module commands, clean some tests, exclute spec files from coverage report * missing file from commit61edd4f1b5
* exclude spec files from coverage report * add support for options in a command function (.get, .set, ...), add support for the SELECT command, implement a couple of commands, fix client socket reconnection strategy, add support for using replicas (RO) in cluster, and more.. * fix client.blPop test * use which to find redis-server path * change command options to work with Symbol rather then WeakSet * implement more commands * Add support for lua scripts in client & muilti, fix client socket initiator, implement simple cluster nodes discovery strategy * replace `callbackify` with `legacyMode` * add the SCAN command and client.scanIterator * rename scanIterator * init benchmark workflow * fix benchmark workflow * fix benchmark workflow * fix benchmark workflow * push coverage report to Coveralls * fix Coveralls * generator lcov (for Coveralls) * fix .nycrc.json * PubSub * add support for all set commands (including sScanIterator) * support pipeline * fix KEEPTTL in SET * remove console.log * add HyperLogLog commands * update README.md (thanks to @guyroyse) * add support for most of the "keys commands" * fix EXPIREAT.spec.ts * add support for date in both EXPIREAT & EXPIRE * add tests * better cluster nodes discorvery strategy after MOVED error, add PubSub test * fix PubSub UNSUBSCRIBE/PUNSUBSCRIBE without channel and/or listener * fix PubSub * add release-it to dev dependencies * Release 4.0.0-next.0 * fix .npmignore * Release 4.0.0-next.1 * fix links in README.md * fix .npmignore * Release 4.0.0-next.2 * add support for all sorted set commands * add support for most stream commands * add missing file from commit53de279afe
* lots of todo commends * make PubSub test more stable * clean ZPOPMAX * add support for lua scripts and modules in cluster, spawn cluster for tests, add some cluster tests, fix pubsub listener arguments * GET.spec.ts * add support for List commands, fix some Sorted Set commands, add some cluster commands, spawn cluster for testing, add support for command options in cluster, and more * add missing file from commitfaab94fab2
* clean ZRANK and ZREVRANK * add XREAD and XREADGROUP commands * remove unused files * implement a couple of more commands, make cluster random iterator be per node (instead of per slot) * Release 4.0.0-next.3 * app spec files to npmignore * fix some code analyzers (LGTM, deepsource, codeclimate) issues * fix CLUSTER_NODES, add some tests * add HSCAN, clean some commands, add tests for generic transformers * add missing files from0feb35a1fb
* update README.md (thanks to @guyroyse) * handle ASK errors, add some commands and tests * Release 4.0.0-next.4 * replace "modern" with "v4" * remove unused imports * add all ACL subcommands, all MODULE subcommands, and some other commands * remove 2 unused imports * fix BITFIELD command * fix XTRIM spec file * clean code * fix package.json types field * better modules support, fix some bugs in legacy mode, add some tests * remove unused function * add test for hScanIterator * change node mimimum version to 12 (latest LTS) * update tsconfig.json to support node 12, run tests on Redis 5 & 6 and on all node live versions * remove future node releases :P * remove "lib" from ts compiler options * Update tsconfig.json * fix build * run some tests only on supported redis versions, use coveralls parallel mode * fix tests * Do not use "timers/promises", fix "isRedisVersionGreaterThan" * skip AbortController tests when not available * use 'fs'.promises instead of 'fs/promises' * add some missing commands * run GETDEL tests only if the redis version is greater than 6.2 * implement some GEO commands, improve scan generic transformer, expose RPUSHX * fix GEOSEARCH & GEOSEARCHSTORE * use socket.setNoDelay and queueMicrotask to improve latency * commands-queue.ts: String length / byte length counting issue (#1630) * Update commands-queue.ts Hopefully fixing #1628 * Reverted 2fa5ea6, and implemented test for byte length check * Changed back to Buffer.byteLength, due to issue author input. Updated test to look for 4 bytes. * Fixed. There were two places that length was calculated. * Removed redundant string assignment * add 2 bytes test as well Co-authored-by: Leibale Eidelman <leibale1998@gmail.com> * fix scripts in multi * do not hide bugs in redis * fix fore7bf09644b
* remove unused import * implement WATCH command, fix ZRANGESTORE & GEOSEARCHSTORE tests * update README.md Co-authored-by: @GuyRoyse * use typedoc to auto generate documentation * run "npm install" before "npm run documentation" * clean documentation workflow * fix WATCH spec file * increase "CLUSTER_NODE_TIMEOUT" to 5000ms to avoid "CLUSTERDOWN" errors in tests * pull cluster state every 100 ms * await meetPromises before pulling the cluster state * enhance the way commanders (client/multi/cluster) get extended with modules and scripts * add test for socket retry strategy * implement more commands * set GETEX minimum version to 6.2 * remove unused imports * add support for multi in cluster * upgrade dependencies * Release 4.0.0-next.5 * remove unused imports * improve benchmarking * use the same Multi with duplicated clients * exclude some files from the documentation, add some exports, clean code * fix #1636 - handle null in multi.exec * remove unused import * add supoprt for tuples in HSET * add FIRST_KEY_INDEX to HSET * add a bunch of missing commands, fix MSET and HELLO, add some tests * add FIRST_KEY_INDEX to MSET and MSETNX * upgrade actions * fix coverallsapp/github-action version * Update documentation.yml * Update documentation.yml * clean code * remove unused imports * use "npm ci" instead of "npm install" * fix `self` binding on client modules, use connection pool for `duplicateConnection` * add client.executeIsolated, rename "duplicateConnection" to "isolated", update README.md (thanks to @GuyRoyse and @SimonPrickett) * update README (thanks to @GuyRoyse), add some tests * try to fix "cluster is down" errors in tests * try to fix "cluster is down" errors in tests * upgrade dependencies * update package-lock * Release 4.0.0-next.6 * fix #1636 - fix WatchError * fix forf1bf0beebf
- remove .only from multi tests * Release 4.0.0-next.7 * update README and other markdown files Co-authored-by: @GuyRoyse & @SimonPrickett * Doc updates. (#1640) * update docs, upgrade dependencies * fix README * Release 4.0.0-rc.0 * Update README.md * update docs, add `connectTimeout` options, fix tls Co-authored-by: Guy Royse <guy@guyroyse.com> * npm update, "fix" some tests, clean code * fix AssertionError import * fix #1642 - fix XREAD, XREADGROUP and XTRIM * fix #1644 - add the QUIT command * add socket.noDelay and socket.keepAlive configurations * Update README.md (#1645) * Update README.md Fixed issue with how connection string was specified. Now you can have user@host without having to specify a password, which just makes more sense * Update client-configuration.md as well Co-authored-by: Leibale Eidelman <leibale1998@gmail.com> * update socket.reconnectStrategy description * fix borken link in v3-to-v4.md * increase test coverage, fix bug in cluster redirection strategy, implement CLIENT_ID, remove unused EXEC command Co-authored-by: Nova <novaw@warrenservices.co.uk> Co-authored-by: Simon Prickett <simon@crudworks.org> Co-authored-by: Guy Royse <guy@guyroyse.com>
This commit is contained in:
13
docs/FAQ.md
Normal file
13
docs/FAQ.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# F.A.Q.
|
||||
|
||||
Nobody has *actually* asked these questions. But, we needed somewhere to put all the important bits and bobs that didn't fit anywhere else. So, here you go!
|
||||
|
||||
## What happens when the network goes down?
|
||||
|
||||
When a socket closed unexpectedly, all the commands that were already sent will reject as they might have been executed on the server. The rest will remain queued in memory until a new socket is established. If the client is closed—either by returning an error from [`reconnectStrategy`](./client-configuration.md#reconnect-strategy) or by manually calling `.disconnect()`—they will be rejected.
|
||||
|
||||
## How are commands batched?
|
||||
|
||||
Commands are pipelined using [`queueMicrotask`](https://nodejs.org/api/globals.html#globals_queuemicrotask_callback). Commands from the same "tick" will be sent in batches and respect the [`writableHighWaterMark`](https://nodejs.org/api/stream.html#stream_new_stream_writable_options).
|
||||
|
||||
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.
|
30
docs/client-configuration.md
Normal file
30
docs/client-configuration.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# `createClient` configuration
|
||||
|
||||
| Property | Default | Description |
|
||||
|--------------------------|------------------------------------------|------------------------------------------------------------------------------------------------------------------------------|
|
||||
| socket | | Object defining socket connection properties |
|
||||
| socket.url | | `[redis[s]:]//[[username][:password]@][host][:port]` |
|
||||
| socket.host | `'localhost'` | Hostname to connect to |
|
||||
| socket.port | `6379` | Port to connect to |
|
||||
| socket.username | | ACL username ([see ACL guide](https://redis.io/topics/acl)) |
|
||||
| socket.password | | ACL password or the old "--requirepass" password |
|
||||
| socket.connectTimeout | `5000` | The timeout for connecting to the Redis Server (in milliseconds) |
|
||||
| socket.noDelay | `true` | Enable/disable the use of [`Nagle's algorithm`](https://nodejs.org/api/net.html#net_socket_setnodelay_nodelay) |
|
||||
| socket.keepAlive | `5000` | Enable/disable the [`keep-alive`](https://nodejs.org/api/net.html#net_socket_setkeepalive_enable_initialdelay) functionality |
|
||||
| socket.tls | | Set to `true` to enable [TLS Configuration](https://nodejs.org/api/tls.html#tls_tls_connect_options_callback) |
|
||||
| socket.reconnectStrategy | `retries => Math.min(retries * 50, 500)` | A function containing the [Reconnect Strategy](#reconnect-strategy) logic |
|
||||
| modules | | Object defining which [Redis Modules](https://redis.io/modules) to include (TODO - document) |
|
||||
| scripts | | Object defining Lua scripts to use with this client. See [Lua Scripts](../README.md#lua-scripts) |
|
||||
| commandsQueueMaxLength | | Maximum length of the client's internal command queue |
|
||||
| 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) |
|
||||
|
||||
## Reconnect Strategy
|
||||
|
||||
You can implement a custom reconnect strategy as a function that should:
|
||||
|
||||
- Receives the number of retries attempted so far.
|
||||
- Should return `number | Error`:
|
||||
- `number`: the time in milliseconds to wait before trying to reconnect again.
|
||||
- `Error`: close the client and flush the commands queue.
|
67
docs/isolated-execution.md
Normal file
67
docs/isolated-execution.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# Isolated Execution
|
||||
|
||||
Sometimes you want to run your commands on an exclusive connection. There are a few reasons to do this:
|
||||
|
||||
- You're using [transactions]() and need to `WATCH` a key or keys for changes.
|
||||
- You want to run a blocking command that will take over the connection, such as `BLPOP` or `BLMOVE`.
|
||||
- You're using the `MONITOR` command which also takes over a connection.
|
||||
|
||||
Below are several examples of how to use isolated execution.
|
||||
|
||||
> NOTE: Behind the scences we're using [`generic-pool`](https://www.npmjs.com/package/generic-pool) to provide a pool of connections that can be isolated. Go there to learn more.
|
||||
|
||||
## The Simple Secnario
|
||||
|
||||
This just isolates execution on a single connection. Do what you want with that connection:
|
||||
|
||||
```typescript
|
||||
await client.executeIsolated(async isolatedClient => {
|
||||
await isolatedClient.set('key', 'value');
|
||||
await isolatedClient.get('key');
|
||||
});
|
||||
```
|
||||
|
||||
## Transactions
|
||||
|
||||
Things get a little more complex with transactions. Here we are `.watch()`ing some keys. If the keys change during the transaction, a `WatchError` is thrown when `.exec()` is called:
|
||||
|
||||
```typescript
|
||||
try {
|
||||
await client.executeIsolated(async isolatedClient => {
|
||||
await isolatedClient.watch('key');
|
||||
|
||||
const multi = isolatedClient.multi()
|
||||
.ping()
|
||||
.get('key');
|
||||
|
||||
if (Math.random() > 0.5) {
|
||||
await isolatedClient.watch('another-key');
|
||||
multi.set('another-key', await isolatedClient.get('another-key') / 2);
|
||||
}
|
||||
|
||||
return multi.exec();
|
||||
});
|
||||
} catch (err) {
|
||||
if (err instanceof WatchError) {
|
||||
// the transaction aborted
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Blocking Commands
|
||||
|
||||
For blocking commands, you can execute a tidy little one-liner:
|
||||
|
||||
```typescript
|
||||
await client.executeIsolated(isolatedClient => isolatedClient.blPop('key'));
|
||||
```
|
||||
|
||||
Or, you can just run the command directly, and provide the `isolated` option:
|
||||
|
||||
```typescript
|
||||
await client.blPop(
|
||||
commandOptions({ isolated: true }),
|
||||
'key'
|
||||
);
|
||||
```
|
35
docs/v3-to-v4.md
Normal file
35
docs/v3-to-v4.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# v3 to v4 Migration Guide
|
||||
|
||||
Version 4 of Node Redis is a major refactor. While we have tried to maintain backwards compatibility where possible, several interfaces have changed. Read this guide to understand the differences and how to implement version 4 in your application.
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
See the [Change Log](../CHANGELOG.md).
|
||||
|
||||
## Promises
|
||||
|
||||
Node Redis now uses native [Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) by default for all functions.
|
||||
|
||||
## Legacy Mode
|
||||
|
||||
Use legacy mode to preserve the backwards compatibility of commands while still getting access to the updated experience:
|
||||
|
||||
```typescript
|
||||
const client = createClient({
|
||||
legacyMode: true
|
||||
});
|
||||
|
||||
// legacy mode
|
||||
client.set('key', 'value', 'NX', (err, reply) => {
|
||||
// ...
|
||||
});
|
||||
|
||||
// version 4 interface is still accessible
|
||||
await client.v4.set('key', 'value', {
|
||||
NX: true
|
||||
});
|
||||
```
|
||||
|
||||
## `createClient`
|
||||
|
||||
The configuration object passed to `createClient` has changed significantly with this release. See the [client configuration guide](./client-configuration.md) for details.
|
Reference in New Issue
Block a user