From 8fb9f97984a8be5e69fae6e6bcc0042d81c095d0 Mon Sep 17 00:00:00 2001 From: luin Date: Tue, 16 Jul 2019 22:39:30 +0800 Subject: [PATCH] fix(cluster): prefer master when there're two same node for a slot --- lib/cluster/ConnectionPool.ts | 8 +++++- test/unit/clusters/ConnectionPool.ts | 28 +++++++++++++++++++++ test/unit/{cluster.ts => clusters/index.ts} | 4 +-- 3 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 test/unit/clusters/ConnectionPool.ts rename test/unit/{cluster.ts => clusters/index.ts} (94%) diff --git a/lib/cluster/ConnectionPool.ts b/lib/cluster/ConnectionPool.ts index f70ea0bf..8db158c3 100644 --- a/lib/cluster/ConnectionPool.ts +++ b/lib/cluster/ConnectionPool.ts @@ -123,7 +123,13 @@ export default class ConnectionPool extends EventEmitter { debug("Reset with %O", nodes); const newNodes = {}; nodes.forEach(node => { - newNodes[getNodeKey(node)] = node; + const key = getNodeKey(node); + + // Don't override the existing (master) node + // when the current one is slave. + if (!(node.readOnly && newNodes[key])) { + newNodes[key] = node; + } }); Object.keys(this.nodes.all).forEach(key => { diff --git a/test/unit/clusters/ConnectionPool.ts b/test/unit/clusters/ConnectionPool.ts new file mode 100644 index 00000000..3ebbdd24 --- /dev/null +++ b/test/unit/clusters/ConnectionPool.ts @@ -0,0 +1,28 @@ +import * as sinon from "sinon"; +import { expect } from "chai"; +import ConnectionPool from "../../../lib/cluster/ConnectionPool"; + +describe("ConnectionPool", () => { + describe("#reset", () => { + it("prefers to master if there are two same node for a slot", () => { + const pool = new ConnectionPool({}); + const stub = sinon.stub(pool, "findOrCreate"); + + pool.reset([ + { host: "127.0.0.1", port: 30001, readOnly: true }, + { host: "127.0.0.1", port: 30001, readOnly: false } + ]); + + expect(stub.callCount).to.eql(1); + expect(stub.firstCall.args[1]).to.eql(false); + + pool.reset([ + { host: "127.0.0.1", port: 30001, readOnly: false }, + { host: "127.0.0.1", port: 30001, readOnly: true } + ]); + + expect(stub.callCount).to.eql(2); + expect(stub.firstCall.args[1]).to.eql(false); + }); + }); +}); diff --git a/test/unit/cluster.ts b/test/unit/clusters/index.ts similarity index 94% rename from test/unit/cluster.ts rename to test/unit/clusters/index.ts index bcf4ed1f..02c6061d 100644 --- a/test/unit/cluster.ts +++ b/test/unit/clusters/index.ts @@ -1,5 +1,5 @@ -import { nodeKeyToRedisOptions } from "../../lib/cluster/util"; -import { Cluster } from "../../lib"; +import { nodeKeyToRedisOptions } from "../../../lib/cluster/util"; +import { Cluster } from "../../../lib"; import * as sinon from "sinon"; import { expect } from "chai";