Skip to content

Commit 97463e9

Browse files
committed
chain pipeline commands
1 parent c1fc0fe commit 97463e9

File tree

3 files changed

+44
-5
lines changed

3 files changed

+44
-5
lines changed

docs/transactions.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,27 @@ await multi.execTyped(); // [string]
2727
You can also [watch](https://redis.io/docs/interact/transactions/#optimistic-locking-using-check-and-set) keys by calling `.watch()`. Your transaction will abort if any of the watched keys change.
2828

2929
The `WATCH` state is stored on the connection (by the server). In case you need to run multiple `WATCH` & `MULTI` in parallel you'll need to use a [pool](./pool.md).
30+
31+
## `execAsPipeline`
32+
33+
`execAsPipeline` will execute the commands without "wrapping" it with `MULTI` & `EXEC` (and lose the transactional semantics).
34+
35+
```javascript
36+
await client.multi()
37+
.get('a')
38+
.get('b')
39+
.execAsPipeline();
40+
```
41+
42+
the diffrence between the above pipeline and `Promise.all`:
43+
44+
```javascript
45+
await Promise.all([
46+
client.get('a'),
47+
client.get('b')
48+
]);
49+
```
50+
51+
is that if the socket disconnects during the pipeline, any unwritten commands will be discarded. i.e. if the socket disconnects after `GET a` is written to the socket, but before `GET b` is:
52+
- using `Promise.all` - the client will try to execute `GET b` when the socket reconnects
53+
- using `execAsPipeline` - `GET b` promise will be rejected as well

docs/v4-to-v5.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,19 @@ await cluster.multi()
125125
.exec();
126126
```
127127

128+
## `MULTI.execAsPipeline()`
129+
130+
```javascript
131+
await client.multi()
132+
.set('a', 'a')
133+
.set('b', 'b')
134+
.execAsPipeline();
135+
```
136+
137+
In older versions, if the socket disconnects during the pipeline execution, i.e. after writing `SET a a` and before `SET b b`, the returned promise is rejected, but `SET b b` will still be executed on the server.
138+
139+
In v5, any unwritten commands (in the same pipeline) will be discarded.
140+
128141
## Commands
129142

130143
### Redis

packages/client/lib/client/index.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -749,11 +749,13 @@ export default class RedisClient<
749749
return Promise.reject(new ClientClosedError());
750750
}
751751

752-
const promise = Promise.all(
753-
commands.map(({ args }) => this._self.#queue.addCommand(args, {
754-
typeMapping: this._commandOptions?.typeMapping
755-
}))
756-
);
752+
const chainId = Symbol('Pipeline Chain'),
753+
promise = Promise.all(
754+
commands.map(({ args }) => this._self.#queue.addCommand(args, {
755+
chainId,
756+
typeMapping: this._commandOptions?.typeMapping
757+
}))
758+
);
757759
this._self.#scheduleWrite();
758760
const result = await promise;
759761

0 commit comments

Comments
 (0)