vert.x icon indicating copy to clipboard operation
vert.x copied to clipboard

Redis: "Connection is closed" exception not handled by exceptionHandler

Open GustavoGramajo opened this issue 3 years ago • 5 comments

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.

GustavoGramajo avatar Jul 12 '22 19:07 GustavoGramajo

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.

bjvickers avatar Jan 17 '23 15:01 bjvickers

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 avatar Apr 07 '23 03:04 wapsa

@wapsa if we call the onException handler, does it still make sense to throw after anyway?

pmlopes avatar Apr 08 '23 17:04 pmlopes

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.

wapsa avatar Apr 13 '23 04:04 wapsa

@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.

wapsa avatar Jun 19 '23 04:06 wapsa