Skip to content

Commit 48dced2

Browse files
authored
fix: auto reconnection hangs (#431)
Closes #431 --------- Co-authored-by: yahiro <yahiro07@users.noreply.github.com>
1 parent 28ead06 commit 48dced2

2 files changed

Lines changed: 50 additions & 4 deletions

File tree

connection.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ export interface SendCommandOptions {
1919
* @default false
2020
*/
2121
returnUint8Arrays?: boolean;
22+
23+
/**
24+
* When this option is set, the command is executed directly without queueing.
25+
*
26+
* @default false
27+
*/
28+
inline?: boolean;
2229
}
2330

2431
export interface Connection {
@@ -126,8 +133,8 @@ export class RedisConnection implements Connection {
126133
): Promise<void> {
127134
try {
128135
password && username
129-
? await this.sendCommand("AUTH", [username, password])
130-
: await this.sendCommand("AUTH", [password]);
136+
? await this.sendCommand("AUTH", [username, password], { inline: true })
137+
: await this.sendCommand("AUTH", [password], { inline: true });
131138
} catch (error) {
132139
if (error instanceof ErrorReplyError) {
133140
throw new AuthenticationError("Authentication failed", {
@@ -143,7 +150,7 @@ export class RedisConnection implements Connection {
143150
db: number | undefined = this.options.db,
144151
): Promise<void> {
145152
if (!db) throw new Error("The database index is undefined.");
146-
await this.sendCommand("SELECT", [db]);
153+
await this.sendCommand("SELECT", [db], { inline: true });
147154
}
148155

149156
private enqueueCommand(
@@ -160,13 +167,16 @@ export class RedisConnection implements Connection {
160167
args?: Array<RedisValue>,
161168
options?: SendCommandOptions,
162169
): Promise<RedisReply> {
163-
const { promise, resolve, reject } = Promise.withResolvers<RedisReply>();
164170
const execute = () =>
165171
this.#protocol.sendCommand(
166172
command,
167173
args ?? kEmptyRedisArgs,
168174
options?.returnUint8Arrays,
169175
);
176+
if (options?.inline) {
177+
return execute();
178+
}
179+
const { promise, resolve, reject } = Promise.withResolvers<RedisReply>();
170180
this.enqueueCommand({ execute, resolve, reject });
171181

172182
return promise;

tests/reconnect_test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { assertEquals } from "../vendor/https/deno.land/std/assert/mod.ts";
2+
import {
3+
beforeAll,
4+
describe,
5+
it,
6+
} from "../vendor/https/deno.land/std/testing/bdd.ts";
7+
import { newClient, nextPort, startRedis, stopRedis } from "./test_util.ts";
8+
9+
describe("reconnect", () => {
10+
let port!: number;
11+
beforeAll(() => {
12+
port = nextPort();
13+
});
14+
15+
it("auto reconnect", async () => {
16+
let server = await startRedis({ port });
17+
const client = await newClient({ hostname: "127.0.0.1", port });
18+
assertEquals(await client.ping(), "PONG");
19+
await stopRedis(server);
20+
server = await startRedis({ port });
21+
assertEquals(await client.ping(), "PONG");
22+
client.close();
23+
await stopRedis(server);
24+
});
25+
26+
it("auto reconnect, with db spec", async () => {
27+
let server = await startRedis({ port });
28+
const client = await newClient({ hostname: "127.0.0.1", port, db: 1 });
29+
assertEquals(await client.ping(), "PONG");
30+
await stopRedis(server);
31+
server = await startRedis({ port });
32+
assertEquals(await client.ping(), "PONG");
33+
client.close();
34+
await stopRedis(server);
35+
});
36+
});

0 commit comments

Comments
 (0)