vert.x
vert.x copied to clipboard
Redis: "Connection is closed" exception not handled by exceptionHandler
Version
Vertx 4.3.0 (Quarkus 2.9.1.Final)
Context
I have a RedisVerticle implementation that is pretty much based on this link. But when i have connection problems (not too often, so it is hard to repro), i get:
redis.setex ->
2022-07-12 13:26:50,820 [vert.x-eventloop-thread-7] ERROR - io.quarkus.vertx.core.runtime.VertxCoreRecorder - Uncaught exception received by Vert.x: java.lang.IllegalStateException: Connection is closed at io.vertx.redis.client.impl.RedisStandaloneConnection.send(RedisStandaloneConnection.java:179) at io.vertx.redis.client.impl.PooledRedisConnection.send(PooledRedisConnection.java:73) at io.vertx.redis.client.impl.RedisSentinelConnection.send(RedisSentinelConnection.java:60) at io.vertx.redis.client.impl.RedisAPIImpl.send(RedisAPIImpl.java:59) at io.vertx.redis.client.RedisAPI.setex(RedisAPI.java:2691) at com.somepackage.cache.RedisVerticle.set(RedisVerticle.java:140)
Expected behavior
If i understood correctly, the handler should be called (i don't see any log related to reconnection attempts, nor i see the connection restored, so i am positive about it not being called).
Extra
-
The application has a couple of endpoints to store, delete and get information from redis, and is deployed in two separate machines. Both apps are behind a load balancer.
-
Sentinel mode is used.
-
I would see this kind of errors once a month, sometimes once in 45 days. When checking the redis cluster, it seems to be just fine. Restarting the application/s fixes the issue, since a new connection is created.
Also getting the same issue, it seems that neither the RedisConnection nor the RedisAPI are notified when the Redis connection has closed. I can't find a handler to detect the close event either.
Same issue for me, checked the code & found below
in RedisStandaloneConnection.java, send & batch functions are not invoking the exception handler for such cases.
if (closed) {
throw new IllegalStateException("Connection is closed");
}
below code will invoke the exception handler and retry code can work
if (closed) {
context.execute(new IllegalStateException("Connection is closed"), onException);
throw new IllegalStateException("Connection is closed");
}
@wapsa if we call the onException handler, does it still make sense to throw after anyway?
Either throwing exception or returning failedFuture is needed to signal a failure.
if (closed) {
context.execute(new IllegalStateException("Connection is closed"), onException);
return Future.failedFuture("Connection is closed");
}
Also, the current command execution & whatever commands are executed until the exceptionHandler code can reconnect/replace the connection, will fail. The client will have to retry in such scenario.
@pmlopes Can I raise a PR for adding above fix? Please let me know how to do this. Currently we have to restart the application whenever this occurs.