Skip to content

Commit d5f2f88

Browse files
authored
feat: AbortSignal support for connect() (#519)
1 parent 079cd4b commit d5f2f88

3 files changed

Lines changed: 35 additions & 0 deletions

File tree

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,19 @@ To consume a redis cluster, you can use
9292

9393
## Advanced Usage
9494

95+
### Handle connection timeout
96+
97+
Connection timeout handling can be implemented with `signal` option:
98+
99+
```ts
100+
import { connect } from "@db/redis";
101+
102+
using redis = await connect({
103+
hostname: "127.0.0.1",
104+
signal: () => AbortSignal.timeout(5_000),
105+
});
106+
```
107+
95108
### Retriable connection
96109

97110
By default, a client's connection will retry a command execution based on

connection.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,13 @@ export interface RedisConnectionOptions {
8383
*/
8484
healthCheckInterval?: number;
8585

86+
/**
87+
* An {@linkcode AbortSignal} which is returned by this function is used to abort an ongoing connection process. With this option, you can implement connection timeout, etc.
88+
*
89+
* Works only in Deno v2.3 or later.
90+
*/
91+
signal?: () => AbortSignal;
92+
8693
/**
8794
* @private
8895
*/
@@ -264,9 +271,12 @@ class RedisConnection
264271

265272
async #connect(retryCount: number) {
266273
try {
274+
const signal: AbortSignal | undefined = this.options?.signal?.() ??
275+
undefined;
267276
const dialOpts: Deno.ConnectOptions = {
268277
hostname: this.hostname,
269278
port: parsePortLike(this.port),
279+
signal,
270280
};
271281
const conn: Deno.Conn = this.options?.tls || this.options?.caCerts != null
272282
? await Deno.connectTls({ ...dialOpts, caCerts: this.options?.caCerts })

tests/commands/connection.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
assertEquals,
55
assertExists,
66
assertInstanceOf,
7+
assertRejects,
78
} from "../../deps/std/assert.ts";
89
import { afterAll, beforeAll, describe, it } from "../../deps/std/testing.ts";
910
import { delay } from "../../deps/std/async.ts";
@@ -123,6 +124,17 @@ export function connectionTests(
123124
client.close();
124125
});
125126

127+
it("supports AbortSignal", async () => {
128+
const ac = new AbortController();
129+
ac.abort();
130+
const error = await assertRejects(async () =>
131+
await connect({
132+
...getOpts(),
133+
signal: () => ac.signal,
134+
}), DOMException);
135+
assertEquals(error.name, "AbortError");
136+
});
137+
126138
it("works with a lazy client", async () => {
127139
const client = createLazyClient(getOpts());
128140
assert(!client.isConnected);

0 commit comments

Comments
 (0)