1
0
mirror of https://github.com/redis/node-redis.git synced 2025-12-09 21:21:11 +03:00

fix: resolve doubly linked list push issue (#3085)

* fix redis sentinel failover

* fix: resolve doubly linked list push issue

* fix semicolon syntax

* correctly set the removed node ref

* fix linked list node iterator

* revert push logic and refactor remove logic

* add linked list tests
This commit is contained in:
Vuong Ngo (Viktor)
2025-10-02 17:39:39 +07:00
committed by GitHub
parent 17fc725536
commit 73413e086c
3 changed files with 59 additions and 11 deletions

View File

@@ -6,7 +6,7 @@ import {
import { equal, deepEqual } from "assert/strict";
describe("DoublyLinkedList", () => {
const list = new DoublyLinkedList();
const list = new DoublyLinkedList<number>();
it("should start empty", () => {
equal(list.length, 0);
@@ -96,6 +96,38 @@ describe("DoublyLinkedList", () => {
}
equal(count, 6);
});
it("should handle remove on empty list", () => {
list.reset();
const node = list.push(1);
list.remove(node);
equal(list.length, 0);
deepEqual(Array.from(list), []);
list.remove(node);
equal(list.length, 0);
deepEqual(Array.from(list), []);
});
it("should safely remove nodes while iterating", () => {
list.reset();
list.push(1);
list.push(2);
list.push(3);
list.push(4);
list.push(5);
const visited: number[] = [];
for (const node of list.nodes()) {
visited.push(node.value);
if (node.value % 2 === 0) {
list.remove(node);
}
}
deepEqual(visited, [1, 2, 3, 4, 5]);
equal(list.length, 3);
deepEqual(Array.from(list), [1, 3, 5]);
});
});
describe("SinglyLinkedList", () => {

View File

@@ -29,7 +29,7 @@ export class DoublyLinkedList<T> {
++this.#length;
if (this.#tail === undefined) {
return this.#tail = this.#head = {
return this.#head = this.#tail = {
previous: this.#head,
next: undefined,
value
@@ -73,7 +73,7 @@ export class DoublyLinkedList<T> {
--this.#length;
const node = this.#head;
if (node.next) {
node.next.previous = node.previous;
node.next.previous = undefined;
this.#head = node.next;
node.next = undefined;
} else {
@@ -83,19 +83,23 @@ export class DoublyLinkedList<T> {
}
remove(node: DoublyLinkedNode<T>) {
if (this.#length === 0) return;
--this.#length;
if (this.#tail === node) {
this.#tail = node.previous;
}
}
if (this.#head === node) {
this.#head = node.next;
} else {
node.previous!.next = node.next;
node.previous = undefined;
if (node.previous) {
node.previous.next = node.next;
}
if (node.next) {
node.next.previous = node.previous;
}
}
node.previous = undefined;
node.next = undefined;
}
@@ -115,8 +119,9 @@ export class DoublyLinkedList<T> {
*nodes() {
let node = this.#head;
while(node) {
const next = node.next
yield node;
node = node.next;
node = next;
}
}
}

View File

@@ -928,6 +928,16 @@ class RedisSentinelInternal<
}
}
#handleSentinelFailure(node: RedisNode) {
const found = this.#sentinelRootNodes.findIndex(
(rootNode) => rootNode.host === node.host && rootNode.port === node.port
);
if (found !== -1) {
this.#sentinelRootNodes.splice(found, 1);
}
this.#reset();
}
async close() {
this.#destroy = true;
@@ -1197,8 +1207,9 @@ class RedisSentinelInternal<
error: err
};
this.emit('client-error', event);
this.#reset();
});
this.#handleSentinelFailure(node);
})
.on('end', () => this.#handleSentinelFailure(node));
this.#sentinelClient = client;
this.#trace(`transform: adding sentinel client connect() to promise list`);