From cf898b3d98a87cc4a5f624fe065879916101f6e9 Mon Sep 17 00:00:00 2001 From: toptobes Date: Mon, 27 Jul 2026 21:50:37 -0500 Subject: [PATCH] fix --- lib/control-connection.js | 7 +++---- lib/metadata/index.js | 15 +++++++++------ test/unit/metadata-tests.js | 17 +++++++++++++++++ 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/lib/control-connection.js b/lib/control-connection.js index fd707529..46f90c8d 100644 --- a/lib/control-connection.js +++ b/lib/control-connection.js @@ -384,6 +384,9 @@ class ControlConnection extends events.EventEmitter { const rsPeers = await c.send(new requests.QueryRequest(selectPeers), null); await this.setPeersInfo(initializing, rsPeers); + this.metadata.setCassandraVersion(this.host.getCassandraVersion()); + this.metadata.buildTokens(this.hosts); + if (!this.initialized) { // resolve protocol version from highest common version among hosts. const highestCommon = types.protocolVersion.getHighestCommon(c, this.hosts); @@ -409,10 +412,6 @@ class ControlConnection extends events.EventEmitter { } } - // To acquire metadata we need to specify the cassandra version - this.metadata.setCassandraVersion(this.host.getCassandraVersion()); - this.metadata.buildTokens(this.hosts); - if (!this.options.isMetadataSyncEnabled) { this.metadata.initialized = true; return; diff --git a/lib/metadata/index.js b/lib/metadata/index.js index b724351b..0482a837 100644 --- a/lib/metadata/index.js +++ b/lib/metadata/index.js @@ -146,7 +146,7 @@ class Metadata { return this.log('error', 'Tokenizer could not be determined'); } //Get a sorted array of tokens - const allSorted = []; + const tempRing = []; //Get a map of const primaryReplicas = {}; //Depending on the amount of tokens, this could be an expensive operation @@ -159,7 +159,7 @@ class Metadata { } h.tokens.forEach((tokenString) => { const token = this.tokenizer.parse(tokenString); - utils.insertSorted(allSorted, token, (t1, t2) => t1.compare(t2)); + tempRing.push(token); primaryReplicas[stringify(token)] = h; }); let dc = datacenters[h.datacenter]; @@ -175,7 +175,7 @@ class Metadata { //Primary replica for given token this.primaryReplicas = primaryReplicas; //All the tokens in ring order - this.ring = allSorted; + this.ring = tempRing.sort((t1, t2) => t1.compare(t2)); // Build TokenRanges. const tokenRanges = new Set(); if (this.ring.length === 1) { @@ -192,12 +192,15 @@ class Metadata { } this.tokenRanges = tokenRanges; //Compute string versions as it's potentially expensive and frequently reused later - this.ringTokensAsStrings = new Array(allSorted.length); - for (let i = 0; i < allSorted.length; i++) { - this.ringTokensAsStrings[i] = stringify(allSorted[i]); + this.ringTokensAsStrings = new Array(tempRing.length); + for (let i = 0; i < tempRing.length; i++) { + this.ringTokensAsStrings[i] = stringify(tempRing[i]); } //Datacenter metadata (host length and racks) this.datacenters = datacenters; + if (this.keyspaces) { + Object.values(this.keyspaces).forEach(k => k.replicas = undefined); + } } /** diff --git a/test/unit/metadata-tests.js b/test/unit/metadata-tests.js index e211db9e..25ee0eb4 100644 --- a/test/unit/metadata-tests.js +++ b/test/unit/metadata-tests.js @@ -2437,6 +2437,23 @@ describe('Metadata', function () { assert.deepEqual(metadata.getReplicas(null, Array.from(ranges)[0]), [h2]); done(); }); + + it('should clear cached keyspace replicas on rebuild', function () { + const metadata = new Metadata(clientOptions.defaultOptions(), null); + metadata.tokenizer = getTokenizer(); + const hosts = new HostMap(); + const h1 = new Host('127.0.0.1', 2, clientOptions.defaultOptions()); + h1.tokens = ['10']; + hosts.set(h1.address, h1); + + assert.deepEqual(metadata.keyspaces, {}); + metadata.keyspaces = { + test_ks: { replicas: { '10': [h1] } } + }; + + metadata.buildTokens(hosts); + assert.deepEqual(metadata.keyspaces, { test_ks: { replicas: undefined } }); + }); }); describe('#newToken()', function () {