Skip to content

Commit 52ce399

Browse files
c00887447tishun
authored andcommitted
Improves the performance of obtaining write connections.
Signed-off-by: c00887447 <[email protected]>
1 parent 73bb51a commit 52ce399

File tree

1 file changed

+30
-33
lines changed

1 file changed

+30
-33
lines changed

src/main/java/io/lettuce/core/cluster/PooledClusterConnectionProvider.java

Lines changed: 30 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -157,47 +157,44 @@ public CompletableFuture<StatefulRedisConnection<K, V>> getConnectionAsync(Conne
157157
}
158158

159159
private CompletableFuture<StatefulRedisConnection<K, V>> getWriteConnection(int slot) {
160+
if (writers[slot] == null) {
161+
stateLock.lock();
162+
try {
163+
if (writers[slot] == null) {
164+
RedisClusterNode master = partitions.getMasterBySlot(slot);
165+
if (master == null) {
166+
clusterEventListener.onUncoveredSlot(slot);
167+
return Futures.failed(new PartitionSelectorException(
168+
"Cannot determine a partition for slot " + slot + ".", partitions.clone()));
169+
}
160170

161-
CompletableFuture<StatefulRedisConnection<K, V>> writer;// avoid races when reconfiguring partitions.
171+
// Use always host and port for slot-oriented operations. We don't want to get reconnected on a different
172+
// host because the nodeId can be handled by a different host.
173+
RedisURI uri = master.getUri();
174+
ConnectionKey key = new ConnectionKey(ConnectionIntent.WRITE, uri.getHost(), uri.getPort());
162175

163-
stateLock.lock();
164-
try {
165-
writer = writers[slot];
166-
} finally {
167-
stateLock.unlock();
168-
}
176+
ConnectionFuture<StatefulRedisConnection<K, V>> future = getConnectionAsync(key);
169177

170-
if (writer == null) {
171-
RedisClusterNode master = partitions.getMasterBySlot(slot);
172-
if (master == null) {
173-
clusterEventListener.onUncoveredSlot(slot);
174-
return Futures.failed(new PartitionSelectorException("Cannot determine a partition for slot " + slot + ".",
175-
partitions.clone()));
176-
}
178+
return future.thenApply(connection -> {
177179

178-
// Use always host and port for slot-oriented operations. We don't want to get reconnected on a different
179-
// host because the nodeId can be handled by a different host.
180-
RedisURI uri = master.getUri();
181-
ConnectionKey key = new ConnectionKey(ConnectionIntent.WRITE, uri.getHost(), uri.getPort());
182-
183-
ConnectionFuture<StatefulRedisConnection<K, V>> future = getConnectionAsync(key);
184-
185-
return future.thenApply(connection -> {
180+
stateLock.lock();
181+
try {
182+
if (writers[slot] == null) {
183+
writers[slot] = CompletableFuture.completedFuture(connection);
184+
}
185+
} finally {
186+
stateLock.unlock();
187+
}
186188

187-
stateLock.lock();
188-
try {
189-
if (writers[slot] == null) {
190-
writers[slot] = CompletableFuture.completedFuture(connection);
191-
}
192-
} finally {
193-
stateLock.unlock();
189+
return connection;
190+
}).toCompletableFuture();
194191
}
195-
196-
return connection;
197-
}).toCompletableFuture();
192+
} finally {
193+
stateLock.unlock();
194+
}
198195
}
199196

200-
return writer;
197+
return writers[slot];
201198
}
202199

203200
private CompletableFuture<StatefulRedisConnection<K, V>> getReadConnection(int slot) {

0 commit comments

Comments
 (0)