Skip to content

Commit 923e698

Browse files
chore: remove deprecated ClientOptions#cancelCommandsOnReconnectFailure (#3328) (#3346)
* chore: remove deprecated ClientOptions#cancelCommandsOnReconnectFailure - removed the option from ClientOptions and ClusterClientOptions and related builders - removed usages from integration tests and unit tests - removed usage from ReconnectionHandler and DefaultEndpoint Signed-off-by: The-East-Wind <[email protected]> * Also remove the documentation on the cancelCommandsOnReconnectFailure option --------- Signed-off-by: The-East-Wind <[email protected]> Co-authored-by: Tihomir Mateev <[email protected]>
1 parent 8e6e63d commit 923e698

File tree

8 files changed

+10
-155
lines changed

8 files changed

+10
-155
lines changed

docs/advanced-usage.md

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -382,26 +382,6 @@ that the command would not be filtered out.</p>
382382
enabled.</p></td>
383383
</tr>
384384
<tr>
385-
<td>Cancel commands on reconnect failure</td>
386-
<td><code>cancelCommandsOnReconnectFailure</code></td>
387-
<td><code>false</code></td>
388-
</tr>
389-
<tr>
390-
<td colspan="3"><p>Since: 3.1, 4.0</p>
391-
<p><strong>This flag is deprecated and should not be used as it can lead
392-
to race conditions and protocol offsets. SSL is natively supported by
393-
Lettuce and does no longer requires the use of SSL tunnels where
394-
protocol traffic can get out of sync.</strong></p>
395-
<p>If this flag is <code>true</code> any queued commands will be
396-
canceled when a reconnect fails within the activation sequence. The
397-
reconnect itself has two phases: Socket connection and
398-
protocol/connection activation. In case a connect timeout occurs, a
399-
connection reset, host lookup fails, this does not affect the
400-
cancellation of commands. In contrast, where the protocol/connection
401-
activation fails due to SSL errors or PING before activating connection
402-
failure, queued commands are canceled.</p></td>
403-
</tr>
404-
<tr>
405385
<td>Policy how to reclaim decode buffer memory</td>
406386
<td><code>decodeBufferPolicy</code></td>
407387
<td><code>ratio-based at 75%</code></td>

src/main/java/io/lettuce/core/ClientOptions.java

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import java.util.function.Predicate;
2929
import java.util.function.Supplier;
3030

31-
import io.lettuce.core.api.StatefulConnection;
3231
import io.lettuce.core.internal.LettuceAssert;
3332
import io.lettuce.core.json.JsonParser;
3433
import io.lettuce.core.json.RedisJsonException;
@@ -56,8 +55,6 @@ public class ClientOptions implements Serializable {
5655

5756
public static final int DEFAULT_BUFFER_USAGE_RATIO = 3;
5857

59-
public static final boolean DEFAULT_CANCEL_CMD_RECONNECT_FAIL = false;
60-
6158
public static final DisconnectedBehavior DEFAULT_DISCONNECTED_BEHAVIOR = DisconnectedBehavior.DEFAULT;
6259

6360
public static final ReauthenticateBehavior DEFAULT_REAUTHENTICATE_BEHAVIOUR = ReauthenticateBehavior.DEFAULT;
@@ -98,8 +95,6 @@ public class ClientOptions implements Serializable {
9895

9996
private final Predicate<RedisCommand<?, ?, ?>> replayFilter;
10097

101-
private final boolean cancelCommandsOnReconnectFailure;
102-
10398
private final DecodeBufferPolicy decodeBufferPolicy;
10499

105100
private final DisconnectedBehavior disconnectedBehavior;
@@ -133,7 +128,6 @@ public class ClientOptions implements Serializable {
133128
protected ClientOptions(Builder builder) {
134129
this.autoReconnect = builder.autoReconnect;
135130
this.replayFilter = builder.replayFilter;
136-
this.cancelCommandsOnReconnectFailure = builder.cancelCommandsOnReconnectFailure;
137131
this.decodeBufferPolicy = builder.decodeBufferPolicy;
138132
this.disconnectedBehavior = builder.disconnectedBehavior;
139133
this.reauthenticateBehavior = builder.reauthenticateBehavior;
@@ -154,7 +148,6 @@ protected ClientOptions(Builder builder) {
154148
protected ClientOptions(ClientOptions original) {
155149
this.autoReconnect = original.isAutoReconnect();
156150
this.replayFilter = original.getReplayFilter();
157-
this.cancelCommandsOnReconnectFailure = original.isCancelCommandsOnReconnectFailure();
158151
this.decodeBufferPolicy = original.getDecodeBufferPolicy();
159152
this.disconnectedBehavior = original.getDisconnectedBehavior();
160153
this.reauthenticateBehavior = original.getReauthenticateBehaviour();
@@ -209,8 +202,6 @@ public static class Builder {
209202

210203
private Predicate<RedisCommand<?, ?, ?>> replayFilter = DEFAULT_REPLAY_FILTER;
211204

212-
private boolean cancelCommandsOnReconnectFailure = DEFAULT_CANCEL_CMD_RECONNECT_FAIL;
213-
214205
private DecodeBufferPolicy decodeBufferPolicy = DecodeBufferPolicies.ratio(DEFAULT_BUFFER_USAGE_RATIO);
215206

216207
private DisconnectedBehavior disconnectedBehavior = DEFAULT_DISCONNECTED_BEHAVIOR;
@@ -271,23 +262,6 @@ public Builder replayFilter(Predicate<RedisCommand<?, ?, ?>> replayFilter) {
271262
return this;
272263
}
273264

274-
/**
275-
* Allows cancelling queued commands in case a reconnect fails.Defaults to {@code false}. See
276-
* {@link #DEFAULT_CANCEL_CMD_RECONNECT_FAIL}. <b>This flag is deprecated and should not be used as it can lead to race
277-
* conditions and protocol offsets. The reason is that it internally calls reset() which causes a protocol offset.</b>
278-
* See {@link StatefulConnection#reset}
279-
*
280-
* @param cancelCommandsOnReconnectFailure true/false
281-
* @return {@code this}
282-
* @deprecated since 6.2, to be removed with 7.0. This feature is unsafe and may cause protocol offsets if true (i.e.
283-
* Redis commands are completed with previous command values).
284-
*/
285-
@Deprecated
286-
public Builder cancelCommandsOnReconnectFailure(boolean cancelCommandsOnReconnectFailure) {
287-
this.cancelCommandsOnReconnectFailure = cancelCommandsOnReconnectFailure;
288-
return this;
289-
}
290-
291265
/**
292266
* Buffer usage ratio for {@link io.lettuce.core.protocol.CommandHandler}. This ratio controls how often bytes are
293267
* discarded during decoding. In particular, when buffer usage reaches {@code bufferUsageRatio / bufferUsageRatio + 1}.
@@ -551,8 +525,7 @@ public ClientOptions build() {
551525
public ClientOptions.Builder mutate() {
552526
Builder builder = new Builder();
553527

554-
builder.autoReconnect(isAutoReconnect()).cancelCommandsOnReconnectFailure(isCancelCommandsOnReconnectFailure())
555-
.replayFilter(getReplayFilter()).decodeBufferPolicy(getDecodeBufferPolicy())
528+
builder.autoReconnect(isAutoReconnect()).replayFilter(getReplayFilter()).decodeBufferPolicy(getDecodeBufferPolicy())
556529
.disconnectedBehavior(getDisconnectedBehavior()).reauthenticateBehavior(getReauthenticateBehaviour())
557530
.readOnlyCommands(getReadOnlyCommands()).publishOnScheduler(isPublishOnScheduler())
558531
.pingBeforeActivateConnection(isPingBeforeActivateConnection()).protocolVersion(getConfiguredProtocolVersion())
@@ -586,18 +559,6 @@ public boolean isAutoReconnect() {
586559
return replayFilter;
587560
}
588561

589-
/**
590-
* If this flag is {@code true} any queued commands will be canceled when a reconnect fails within the activation sequence.
591-
* Default is {@code false}.
592-
*
593-
* @return {@code true} if commands should be cancelled on reconnect failures.
594-
* @deprecated since 6.2, to be removed with 7.0. See {@link Builder#cancelCommandsOnReconnectFailure(boolean)}.
595-
*/
596-
@Deprecated
597-
public boolean isCancelCommandsOnReconnectFailure() {
598-
return cancelCommandsOnReconnectFailure;
599-
}
600-
601562
/**
602563
* Returns the {@link DecodeBufferPolicy} used to reclaim memory.
603564
*

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

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,7 @@ public static ClusterClientOptions.Builder builder(ClientOptions clientOptions)
130130
}
131131

132132
Builder builder = new Builder();
133-
builder.autoReconnect(clientOptions.isAutoReconnect())
134-
.cancelCommandsOnReconnectFailure(clientOptions.isCancelCommandsOnReconnectFailure())
135-
.decodeBufferPolicy(clientOptions.getDecodeBufferPolicy())
133+
builder.autoReconnect(clientOptions.isAutoReconnect()).decodeBufferPolicy(clientOptions.getDecodeBufferPolicy())
136134
.disconnectedBehavior(clientOptions.getDisconnectedBehavior())
137135
.reauthenticateBehavior(clientOptions.getReauthenticateBehaviour())
138136
.pingBeforeActivateConnection(clientOptions.isPingBeforeActivateConnection())
@@ -193,20 +191,6 @@ public Builder bufferUsageRatio(int bufferUsageRatio) {
193191
return this;
194192
}
195193

196-
/**
197-
*
198-
* @param cancelCommandsOnReconnectFailure true/false
199-
* @return
200-
* @deprecated since 6.2, to be removed with 7.0. This feature is unsafe and may cause protocol offsets if true (i.e.
201-
* Redis commands are completed with previous command values).
202-
*/
203-
@Override
204-
@Deprecated
205-
public Builder cancelCommandsOnReconnectFailure(boolean cancelCommandsOnReconnectFailure) {
206-
super.cancelCommandsOnReconnectFailure(cancelCommandsOnReconnectFailure);
207-
return this;
208-
}
209-
210194
@Override
211195
public Builder decodeBufferPolicy(DecodeBufferPolicy decodeBufferPolicy) {
212196
super.decodeBufferPolicy(decodeBufferPolicy);
@@ -360,14 +344,14 @@ public ClusterClientOptions.Builder mutate() {
360344

361345
Builder builder = new Builder();
362346

363-
builder.autoReconnect(isAutoReconnect()).cancelCommandsOnReconnectFailure(isCancelCommandsOnReconnectFailure())
364-
.decodeBufferPolicy(getDecodeBufferPolicy()).disconnectedBehavior(getDisconnectedBehavior())
365-
.reauthenticateBehavior(getReauthenticateBehaviour()).maxRedirects(getMaxRedirects())
366-
.publishOnScheduler(isPublishOnScheduler()).pingBeforeActivateConnection(isPingBeforeActivateConnection())
367-
.protocolVersion(getConfiguredProtocolVersion()).readOnlyCommands(getReadOnlyCommands())
368-
.requestQueueSize(getRequestQueueSize()).scriptCharset(getScriptCharset()).socketOptions(getSocketOptions())
369-
.sslOptions(getSslOptions()).suspendReconnectOnProtocolFailure(isSuspendReconnectOnProtocolFailure())
370-
.timeoutOptions(getTimeoutOptions()).topologyRefreshOptions(getTopologyRefreshOptions())
347+
builder.autoReconnect(isAutoReconnect()).decodeBufferPolicy(getDecodeBufferPolicy())
348+
.disconnectedBehavior(getDisconnectedBehavior()).reauthenticateBehavior(getReauthenticateBehaviour())
349+
.maxRedirects(getMaxRedirects()).publishOnScheduler(isPublishOnScheduler())
350+
.pingBeforeActivateConnection(isPingBeforeActivateConnection()).protocolVersion(getConfiguredProtocolVersion())
351+
.readOnlyCommands(getReadOnlyCommands()).requestQueueSize(getRequestQueueSize())
352+
.scriptCharset(getScriptCharset()).socketOptions(getSocketOptions()).sslOptions(getSslOptions())
353+
.suspendReconnectOnProtocolFailure(isSuspendReconnectOnProtocolFailure()).timeoutOptions(getTimeoutOptions())
354+
.topologyRefreshOptions(getTopologyRefreshOptions())
371355
.validateClusterNodeMembership(isValidateClusterNodeMembership()).nodeFilter(getNodeFilter());
372356

373357
return builder;

src/main/java/io/lettuce/core/protocol/DefaultEndpoint.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -495,10 +495,6 @@ public void notifyChannelActive(Channel channel) {
495495
logger.debug("{} channelActive() ran into an exception", logPrefix());
496496
}
497497

498-
if (clientOptions.isCancelCommandsOnReconnectFailure()) {
499-
reset();
500-
}
501-
502498
throw e;
503499
}
504500
});

src/main/java/io/lettuce/core/protocol/ReconnectionHandler.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,6 @@ private void reconnect0(CompletableFuture<Channel> result, SocketAddress remoteA
157157
return;
158158
}
159159

160-
if (clientOptions.isCancelCommandsOnReconnectFailure()) {
161-
connectionFacade.reset();
162-
}
163-
164160
if (clientOptions.isSuspendReconnectOnProtocolFailure()) {
165161

166162
logger.error("Disabling autoReconnect due to initialization failure", throwable);

src/test/java/io/lettuce/core/ClientOptionsUnitTests.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import io.lettuce.core.protocol.Command;
1818
import io.lettuce.core.protocol.CommandType;
1919
import io.lettuce.core.protocol.ProtocolVersion;
20-
import reactor.core.publisher.Mono;
2120

2221
/**
2322
* Unit tests for {@link ClientOptions}.
@@ -106,7 +105,6 @@ public JsonValue fromObject(Object object) {
106105

107106
void checkAssertions(ClientOptions sut) {
108107
assertThat(sut.isAutoReconnect()).isTrue();
109-
assertThat(sut.isCancelCommandsOnReconnectFailure()).isFalse();
110108
assertThat(sut.getProtocolVersion()).isEqualTo(ProtocolVersion.RESP3);
111109
assertThat(sut.isSuspendReconnectOnProtocolFailure()).isFalse();
112110
assertThat(sut.getDisconnectedBehavior()).isEqualTo(ClientOptions.DisconnectedBehavior.DEFAULT);

src/test/java/io/lettuce/core/cluster/ClusterClientOptionsUnitTests.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ void testCopy() {
4141
assertThat(copy.isValidateClusterNodeMembership()).isEqualTo(options.isValidateClusterNodeMembership());
4242
assertThat(copy.getRequestQueueSize()).isEqualTo(options.getRequestQueueSize());
4343
assertThat(copy.isAutoReconnect()).isEqualTo(options.isAutoReconnect());
44-
assertThat(copy.isCancelCommandsOnReconnectFailure()).isEqualTo(options.isCancelCommandsOnReconnectFailure());
4544
assertThat(copy.isSuspendReconnectOnProtocolFailure()).isEqualTo(options.isSuspendReconnectOnProtocolFailure());
4645
assertThat(copy.getMaxRedirects()).isEqualTo(options.getMaxRedirects());
4746
assertThat(copy.getScriptCharset()).isEqualTo(StandardCharsets.UTF_8);
@@ -73,8 +72,6 @@ void builderFromDefaultClientOptions() {
7372
assertThat(clusterClientOptions.getRequestQueueSize()).isEqualTo(clusterClientOptions.getRequestQueueSize());
7473
assertThat(clusterClientOptions.isAutoReconnect()).isEqualTo(clusterClientOptions.isAutoReconnect());
7574
assertThat(clusterClientOptions.isCloseStaleConnections()).isEqualTo(clusterClientOptions.isCloseStaleConnections());
76-
assertThat(clusterClientOptions.isCancelCommandsOnReconnectFailure())
77-
.isEqualTo(clusterClientOptions.isCancelCommandsOnReconnectFailure());
7875
assertThat(clusterClientOptions.isPublishOnScheduler()).isEqualTo(clusterClientOptions.isPublishOnScheduler());
7976
assertThat(clusterClientOptions.isSuspendReconnectOnProtocolFailure())
8077
.isEqualTo(clusterClientOptions.isSuspendReconnectOnProtocolFailure());
@@ -97,7 +94,6 @@ void builderFromClusterClientOptions() {
9794
assertThat(copy.isValidateClusterNodeMembership()).isEqualTo(options.isValidateClusterNodeMembership());
9895
assertThat(copy.getRequestQueueSize()).isEqualTo(options.getRequestQueueSize());
9996
assertThat(copy.isAutoReconnect()).isEqualTo(options.isAutoReconnect());
100-
assertThat(copy.isCancelCommandsOnReconnectFailure()).isEqualTo(options.isCancelCommandsOnReconnectFailure());
10197
assertThat(copy.isSuspendReconnectOnProtocolFailure()).isEqualTo(options.isSuspendReconnectOnProtocolFailure());
10298
assertThat(copy.getMaxRedirects()).isEqualTo(options.getMaxRedirects());
10399
assertThat(copy.getScriptCharset()).isEqualTo(options.getScriptCharset());

src/test/java/io/lettuce/core/protocol/ConnectionFailureIntegrationTests.java

Lines changed: 0 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -175,62 +175,6 @@ void failOnReconnectShouldSendEvents() throws Exception {
175175
}
176176
}
177177

178-
/**
179-
* Simulates a failure on reconnect by changing the port to a invalid server and triggering a reconnect. Meanwhile a command
180-
* is fired to the connection and the watchdog is triggered afterwards to reconnect.
181-
*
182-
* Expectation: Queued commands are canceled (reset), subsequent commands contain the connection exception.
183-
*
184-
* @throws Exception
185-
*/
186-
@Test
187-
void cancelCommandsOnReconnectFailure() throws Exception {
188-
189-
client.setOptions(ClientOptions.builder().cancelCommandsOnReconnectFailure(true)
190-
.timeoutOptions(TimeoutOptions.builder().timeoutCommands(false).build()).build());
191-
192-
RandomResponseServer ts = getRandomResponseServer();
193-
194-
RedisURI redisUri = RedisURI.create(defaultRedisUri.toURI());
195-
196-
try {
197-
RedisAsyncCommandsImpl<String, String> connection = (RedisAsyncCommandsImpl<String, String>) client
198-
.connect(redisUri).async();
199-
ConnectionWatchdog connectionWatchdog = ConnectionTestUtil
200-
.getConnectionWatchdog(connection.getStatefulConnection());
201-
202-
assertThat(connectionWatchdog.isListenOnChannelInactive()).isTrue();
203-
204-
connectionWatchdog.setReconnectSuspended(true);
205-
redisUri.setPort(TestSettings.nonexistentPort());
206-
207-
connection.quit();
208-
Wait.untilTrue(() -> !connection.getStatefulConnection().isOpen()).waitOrTimeout();
209-
210-
RedisFuture<String> set1 = connection.set(key, value);
211-
RedisFuture<String> set2 = connection.set(key, value);
212-
213-
assertThat(set1.isDone()).isFalse();
214-
assertThat(set1.isCancelled()).isFalse();
215-
216-
assertThat(connection.getStatefulConnection().isOpen()).isFalse();
217-
connectionWatchdog.setReconnectSuspended(false);
218-
connectionWatchdog.run(0);
219-
Delay.delay(Duration.ofMillis(500));
220-
assertThat(connection.getStatefulConnection().isOpen()).isFalse();
221-
222-
assertThatThrownBy(set1::get).isInstanceOf(CancellationException.class).hasNoCause();
223-
assertThatThrownBy(set2::get).isInstanceOf(CancellationException.class).hasNoCause();
224-
225-
assertThatThrownBy(() -> TestFutures.awaitOrTimeout(connection.info())).isInstanceOf(RedisException.class)
226-
.hasMessageContaining("Invalid first byte");
227-
228-
connection.getStatefulConnection().close();
229-
} finally {
230-
ts.shutdown();
231-
}
232-
}
233-
234178
@Test
235179
void emitEventOnReconnectFailure() throws Exception {
236180

0 commit comments

Comments
 (0)