Skip to content

Commit 2058db3

Browse files
committed
chore: better error reporting for ConnectionWatchDog
1 parent 19e6463 commit 2058db3

File tree

2 files changed

+41
-33
lines changed

2 files changed

+41
-33
lines changed

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

+39-32
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,15 @@
2121

2222
import java.net.SocketAddress;
2323
import java.time.Duration;
24-
import java.util.concurrent.CancellationException;
2524
import java.util.concurrent.CompletableFuture;
2625
import java.util.concurrent.TimeUnit;
2726
import java.util.concurrent.atomic.AtomicBoolean;
27+
import java.util.function.Supplier;
2828

2929
import io.lettuce.core.ClientOptions;
3030
import io.lettuce.core.ConnectionBuilder;
3131
import io.lettuce.core.ConnectionEvents;
32+
import io.lettuce.core.RedisException;
3233
import io.lettuce.core.event.EventBus;
3334
import io.lettuce.core.event.connection.ReconnectAttemptEvent;
3435
import io.lettuce.core.event.connection.ReconnectFailedEvent;
@@ -215,20 +216,11 @@ public void channelInactive(ChannelHandlerContext ctx) throws Exception {
215216
channel = null;
216217

217218
if (listenOnChannelInactive && !reconnectionHandler.isReconnectSuspended()) {
218-
if (!isEventLoopGroupActive()) {
219-
logger.debug("isEventLoopGroupActive() == false");
220-
return;
221-
}
222-
223-
if (!isListenOnChannelInactive()) {
224-
logger.debug("Skip reconnect scheduling, listener disabled");
225-
return;
226-
}
227-
228219
if (!useAutoBatchFlushEndpoint) {
229220
this.scheduleReconnect();
221+
} else {
222+
doReconnectOnAutoBatchFlushEndpointQuiescence = this::scheduleReconnect;
230223
}
231-
doReconnectOnAutoBatchFlushEndpointQuiescence = this::scheduleReconnect;
232224
// otherwise, will be called later by BatchFlushEndpoint#onEndpointQuiescence
233225
} else {
234226
logger.debug("{} Reconnect scheduling disabled", logPrefix(), ctx);
@@ -237,7 +229,7 @@ public void channelInactive(ChannelHandlerContext ctx) throws Exception {
237229
super.channelInactive(ctx);
238230
}
239231

240-
boolean willReconnect() {
232+
boolean willReconnectOnAutoBatchFlushEndpointQuiescence() {
241233
return doReconnectOnAutoBatchFlushEndpointQuiescence != null;
242234
}
243235

@@ -261,14 +253,16 @@ public void scheduleReconnect() {
261253
logger.debug("{} scheduleReconnect()", logPrefix());
262254

263255
if (!isEventLoopGroupActive()) {
264-
logger.debug("isEventLoopGroupActive() == false");
265-
notifyEndpointFailedToConnectIfNeeded();
256+
final String errMsg = "isEventLoopGroupActive() == false";
257+
logger.debug(errMsg);
258+
notifyEndpointFailedToConnectIfNeeded(errMsg);
266259
return;
267260
}
268261

269262
if (!isListenOnChannelInactive()) {
270-
logger.debug("Skip reconnect scheduling, listener disabled");
271-
notifyEndpointFailedToConnectIfNeeded();
263+
final String errMsg = "Skip reconnect scheduling, listener disabled";
264+
logger.debug(errMsg);
265+
notifyEndpointFailedToConnectIfNeeded(errMsg);
272266
return;
273267
}
274268

@@ -285,8 +279,9 @@ public void scheduleReconnect() {
285279
reconnectScheduleTimeout = null;
286280

287281
if (!isEventLoopGroupActive()) {
288-
logger.warn("Cannot execute scheduled reconnect timer, reconnect workers are terminated");
289-
notifyEndpointFailedToConnectIfNeeded();
282+
final String errMsg = "Cannot execute scheduled reconnect timer, reconnect workers are terminated";
283+
logger.warn(errMsg);
284+
notifyEndpointFailedToConnectIfNeeded(errMsg);
290285
return;
291286
}
292287

@@ -302,17 +297,25 @@ public void scheduleReconnect() {
302297
}
303298
} else {
304299
logger.debug("{} Skipping scheduleReconnect() because I have an active channel", logPrefix());
305-
notifyEndpointFailedToConnectIfNeeded();
300+
notifyEndpointFailedToConnectIfNeeded("Skipping scheduleReconnect() because I have an active channel");
301+
}
302+
}
303+
304+
private void notifyEndpointFailedToConnectIfNeeded(String msg) {
305+
if (useAutoBatchFlushEndpoint) {
306+
((AutoBatchFlushEndpoint) endpoint).notifyReconnectFailed(new RedisException(msg));
306307
}
307308
}
308309

309-
private void notifyEndpointFailedToConnectIfNeeded() {
310-
notifyEndpointFailedToConnectIfNeeded(new CancellationException());
310+
private void notifyEndpointFailedToConnectIfNeeded(Throwable t) {
311+
if (useAutoBatchFlushEndpoint) {
312+
((AutoBatchFlushEndpoint) endpoint).notifyReconnectFailed(t);
313+
}
311314
}
312315

313-
private void notifyEndpointFailedToConnectIfNeeded(Exception e) {
316+
private void notifyEndpointFailedToConnectIfNeeded(Supplier<Throwable> throwableSupplier) {
314317
if (useAutoBatchFlushEndpoint) {
315-
((AutoBatchFlushEndpoint) endpoint).notifyReconnectFailed(e);
318+
((AutoBatchFlushEndpoint) endpoint).notifyReconnectFailed(throwableSupplier.get());
316319
}
317320
}
318321

@@ -335,26 +338,29 @@ public void run(int attempt) throws Exception {
335338
* @param delay retry delay.
336339
* @throws Exception when reconnection fails.
337340
*/
338-
private void run(int attempt, Duration delay) throws Exception {
341+
private void run(int attempt, Duration delay) {
339342

340343
reconnectSchedulerSync.set(false);
341344
reconnectScheduleTimeout = null;
342345

343346
if (!isEventLoopGroupActive()) {
344-
logger.debug("isEventLoopGroupActive() == false");
345-
notifyEndpointFailedToConnectIfNeeded();
347+
final String errMsg = "isEventLoopGroupActive() == false";
348+
logger.debug(errMsg);
349+
notifyEndpointFailedToConnectIfNeeded(errMsg);
346350
return;
347351
}
348352

349353
if (!isListenOnChannelInactive()) {
350-
logger.debug("Skip reconnect scheduling, listener disabled");
351-
notifyEndpointFailedToConnectIfNeeded();
354+
final String errMsg = "Skip reconnect scheduling, listener disabled";
355+
logger.debug(errMsg);
356+
notifyEndpointFailedToConnectIfNeeded(errMsg);
352357
return;
353358
}
354359

355360
if (isReconnectSuspended()) {
356-
logger.debug("Skip reconnect scheduling, reconnect is suspended");
357-
notifyEndpointFailedToConnectIfNeeded();
361+
final String msg = "Skip reconnect scheduling, reconnect is suspended";
362+
logger.debug(msg);
363+
notifyEndpointFailedToConnectIfNeeded(msg);
358364
return;
359365
}
360366

@@ -411,7 +417,8 @@ private void run(int attempt, Duration delay) throws Exception {
411417
if (!isReconnectSuspended()) {
412418
scheduleReconnect();
413419
} else {
414-
notifyEndpointFailedToConnectIfNeeded();
420+
notifyEndpointFailedToConnectIfNeeded(
421+
() -> new RedisException("got error and then reconnect is suspended", t));
415422
}
416423
});
417424
} catch (Exception e) {

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,8 @@ public void notifyChannelInactiveAfterWatchdogDecision(Channel channel,
390390
return;
391391
}
392392

393-
boolean willReconnect = connectionWatchdog != null && connectionWatchdog.willReconnect();
393+
boolean willReconnect = connectionWatchdog != null
394+
&& connectionWatchdog.willReconnectOnAutoBatchFlushEndpointQuiescence();
394395
RedisException exception = null;
395396
// Unlike DefaultEndpoint, here we don't check reliability since connectionWatchdog.willReconnect() already does it.
396397
if (isClosed()) {

0 commit comments

Comments
 (0)