lettuce icon indicating copy to clipboard operation
lettuce copied to clipboard

NullPointerException in CommandHandler when establishing connections

Open zubchenok opened this issue 1 year ago • 3 comments

Bug Report

Current Behavior

NullPointerException happens when trying to establish large amount 1000000 of connections in 100 threads concurrently.

Stack trace
io.lettuce.core.RedisConnectionException: Unable to connect to 10.0.10.8/<unresolved>:6379
  at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:78)
  at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:56)
  at io.lettuce.core.cluster.PooledClusterConnectionProvider.lambda$getConnectionAsync$6(PooledClusterConnectionProvider.java:433)
  at java.base/java.util.concurrent.CompletableFuture.uniHandle(CompletableFuture.java:934)
  at java.base/java.util.concurrent.CompletableFuture$UniHandle.tryFire(CompletableFuture.java:911)
  at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
  at java.base/java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:2162)
  at io.lettuce.core.AbstractRedisClient.lambda$null$5(AbstractRedisClient.java:470)
  at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863)
  at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:841)
  at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
  at java.base/java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:2162)
  at io.lettuce.core.protocol.RedisHandshakeHandler.lambda$fail$4(RedisHandshakeHandler.java:139)
  at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:578)
  at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:552)
  at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:491)
  at io.netty.util.concurrent.DefaultPromise.addListener(DefaultPromise.java:184)
  at io.netty.channel.DefaultChannelPromise.addListener(DefaultChannelPromise.java:95)
  at io.netty.channel.DefaultChannelPromise.addListener(DefaultChannelPromise.java:30)
  at io.lettuce.core.protocol.RedisHandshakeHandler.fail(RedisHandshakeHandler.java:138)
  at io.lettuce.core.protocol.RedisHandshakeHandler.lambda$channelActive$3(RedisHandshakeHandler.java:107)
  at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863)
  at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:841)
  at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
  at java.base/java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:2162)
  at io.lettuce.core.RedisHandshake.lambda$tryHandshakeResp3$1(RedisHandshake.java:105)
  at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863)
  at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:841)
  at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
  at java.base/java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:2162)
  at io.lettuce.core.protocol.AsyncCommand.doCompleteExceptionally(AsyncCommand.java:139)
  at io.lettuce.core.protocol.AsyncCommand.completeExceptionally(AsyncCommand.java:132)
  at io.lettuce.core.protocol.CommandHandler.exceptionCaught(CommandHandler.java:276)
  at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:302)
  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:381)
  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
  at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
  at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
  at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
  at io.netty.channel.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:795)
  at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:480)
  at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:378)
  at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
  at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
  at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
  at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.NullPointerException: Cannot invoke "io.netty.buffer.ByteBuf.refCnt()" because "this.buffer" is null
  at io.lettuce.core.protocol.CommandHandler.channelRead(CommandHandler.java:582)
  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
  at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
  at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
  at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
  at io.netty.channel.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:795)
  at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:480)
  at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:378)
  at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
  at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
  at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
  at java.base/java.lang.Thread.run(Thread.java:833)

Input Code

Input Code
Scheduler scheduler = Schedulers.from(Executors.newCachedThreadPool());
Flowable
    .range(0, 1000000)
    .flatMapCompletable(x -> Completable
        .fromAction(() -> {
            for (int i = 0; i < 3; ++i) {
                long key = ThreadLocalRandom.current().nextLong();
                byte[] bytes = ByteBuffer.wrap(new byte[8]).putLong(key).array();
                lettuce.connect(ByteArrayCodec.INSTANCE).sync().objectIdletime(bytes);
            }
        })
        .subscribeOn(scheduler), false, 100
    )
    .blockingAwait();

Expected behavior/code

No NPE should happen in CommandHandler class even if it has no sense to create 1000000 connections.

Environment

  • Lettuce version(s): 6.1.5.RELEASE and 6.2.0.RELEASE
  • Redis version: 6.0.12
  • Linux with netty EPOLL enabled

zubchenok avatar Aug 04 '22 17:08 zubchenok

For some reason, there's a read before/after a buffer was set to null. An earlier error must have happened. Please provide further details.

mp911de avatar Nov 22 '22 10:11 mp911de

Just a useless update: I need more time to provide additional details.w

zubchenok avatar Dec 14 '22 12:12 zubchenok

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 30 days this issue will be closed.

github-actions[bot] avatar Apr 26 '24 00:04 github-actions[bot]