-
Notifications
You must be signed in to change notification settings - Fork 119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Getting RuntimeException "java.lang.RuntimeException: Multi is a Map" while HGETALL with redis-server version 6.2.5. #347
Comments
Hi @navi2589 this is not a bug IMHO. I've recreated your issue: package io.vertx.test.redis;
import io.vertx.ext.unit.Async;
import io.vertx.ext.unit.TestContext;
import io.vertx.ext.unit.junit.RunTestOnContext;
import io.vertx.ext.unit.junit.VertxUnitRunner;
import io.vertx.redis.client.Redis;
import io.vertx.redis.client.RedisOptions;
import org.junit.*;
import org.junit.runner.RunWith;
import org.testcontainers.containers.GenericContainer;
import java.util.Arrays;
import java.util.UUID;
import static io.vertx.redis.client.Command.*;
import static io.vertx.redis.client.Request.cmd;
@RunWith(VertxUnitRunner.class)
public class RedisClient6HGETALLTest {
@Rule
public final RunTestOnContext rule = new RunTestOnContext();
@ClassRule
public static final GenericContainer<?> redis = new GenericContainer<>("redis:6.2.5")
.withExposedPorts(6379);
private Redis client;
@Before
public void before(TestContext should) {
final Async before = should.async();
client = Redis.createClient(
rule.vertx(),
new RedisOptions().setConnectionString("redis://" + redis.getHost() + ":" + redis.getFirstMappedPort() + "?client=tester"));
client.batch(Arrays.asList(
cmd(HSET).arg("PROD-SUPPORT.Interface.PROVIDERS_7773").arg("field1").arg("Hello"),
cmd(HSET).arg("PROD-SUPPORT.Interface.PROVIDERS_7773").arg("field2").arg("World")
))
.onFailure(should::fail)
.onSuccess(ok -> before.complete());
}
@After
public void after() {
client.close();
}
private static String makeKey() {
return UUID.randomUUID().toString();
}
@Test(timeout = 10_000L)
public void testBasicInterop(TestContext should) {
final Async test = should.async();
client.send(cmd(HGETALL).arg("PROD-SUPPORT.Interface.PROVIDERS_7773"))
.onFailure(should::fail)
.onSuccess(response -> {
Object getResult = response.get(1);
System.out.println(getResult.toString());
test.complete();
});
}
} What is happening is that the redis server is returning a message as:
The https://github.com/antirez/RESP3/blob/master/spec.md#map-type Which means you cannot look up data using a position, you can locate data using the key, for example: Object getResult = response.get("field1"); While this used to work form redis <6.0.0 (the old protocol didn't support Maps only Arrays) the vert.x client always had a way to emulate the behavior. You should use the right getter in this case. |
@pmlopes Thanks for clarifying . |
We could have the multi store a linked hash map and compute the integer index by looping the entries. Yet if I'm not mistaken Redis 3 is EOL by July 2023. I'm not sure if it's worth the work for less than 1 year? If could try a PR with the idea listed above and we can see... |
Questions
Getting RuntimeException "java.lang.RuntimeException: Multi is a Map" while HGETALL with redis-server version 6.2.5.
Same is code is working with redis-server version "3.2.6".
4.3.2
Which version(s) did you encounter this bug ?
`
`
Context
Getting RuntimeException "java.lang.RuntimeException: Multi is a Map" while HGETALL with redis-server version 6.2.5.
Same is code is working with redis-server version "3.2.6".
java.lang.RuntimeException: Multi is a Map at io.vertx.redis.client.impl.types.MultiType.get(MultiType.java:114) at com.example.starter.MainVerticle.lambda$start$0(MainVerticle.java:25) at io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:141) at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60) at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211) at io.vertx.core.impl.future.Composition$1.onSuccess(Composition.java:62) at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60) at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211) at io.vertx.core.impl.future.Eventually$1.onSuccess(Eventually.java:44) at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60) at io.vertx.core.impl.future.SucceededFuture.addListener(SucceededFuture.java:88) at io.vertx.core.impl.future.Eventually.onSuccess(Eventually.java:41) at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60) at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211) at io.vertx.core.impl.future.PromiseImpl.tryComplete(PromiseImpl.java:23) at io.vertx.redis.client.impl.RedisStandaloneConnection.handle(RedisStandaloneConnection.java:409) at io.vertx.redis.client.impl.RESPParser.handleResponse(RESPParser.java:296) at io.vertx.redis.client.impl.RESPParser.handle(RESPParser.java:128) at io.vertx.redis.client.impl.RESPParser.handle(RESPParser.java:24) at io.vertx.core.net.impl.NetSocketImpl.lambda$new$1(NetSocketImpl.java:98) at io.vertx.core.streams.impl.InboundBuffer.handleEvent(InboundBuffer.java:239) at io.vertx.core.streams.impl.InboundBuffer.write(InboundBuffer.java:129) at io.vertx.core.net.impl.NetSocketImpl$DataMessageHandler.handle(NetSocketImpl.java:418) at io.vertx.core.impl.EventLoopContext.emit(EventLoopContext.java:55) at io.vertx.core.impl.ContextBase.emit(ContextBase.java:239) at io.vertx.core.net.impl.NetSocketImpl.handleMessage(NetSocketImpl.java:394) at io.vertx.core.net.impl.ConnectionBase.read(ConnectionBase.java:155) at io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:153) 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.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:722) at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:658) at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:584) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:496) 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)
Do you have a reproducer?
package com.example.starter;
import io.vertx.core.*;
import io.vertx.redis.client.Redis;
import io.vertx.redis.client.Request;
import io.vertx.redis.client.Response;
import static io.vertx.redis.client.Command.HGETALL;
public class MainVerticle extends AbstractVerticle {
@OverRide
public void start(Promise startPromise) throws Exception {
}
}
Steps to reproduce
Extra
The text was updated successfully, but these errors were encountered: