Git Product home page Git Product logo

redis-protocol's Introduction

A very fast Redis client for the JVM.

Description of each module:

redisgen/
  Scrapes the redis.io/commands page and produce various typed clients and servers, very extensible

util/
  Some common encoding and data structures
client/
  Leverages the protocol module for encoding and decoding. Supports both synchronous
  and asynchronous pipelined requests from the RedisClient. Supports 2.6 commands.
protocol/
  Redis protocol encoder / decoder based on input/outputstreams. This is the
  fastest implementation if blocking i/o is ok for your use case.
benchmark/
  A redis-benchmark clone that uses this Java client for comparison testing.

netty/
  A netty 3.5.X compatible codecs for building Redis clients
netty-client/
  Complete client except for MULTI/EXEC.

netty4/
  A netty 4.0.0.Alpha1 compatible codec for building Redis clients
netty4-server/
  A very high performance in-JVM memory redis server clone

util/
  Some library functions used by both the blocking client and the netty clients

In the experiments branch you can find:
  - finagle
  - vertx
  - NIO bytebuffers
  - HBase Loader
  - and more!

Maven dependency:

    <dependency>
      <groupId>com.github.spullara.redis</groupId>
      <artifactId>client</artifactId>
      <version>0.7</version>
    </dependency>

Benchmarks

Various redis client benchmarks

- JDK 7u6
- redis-server 2.4.4
- for (i <- 0 to 1,000,000) { set(i, "value") }
- Conditions
  - localhost
  - 1 connection
  - request and wait for response
- Results
  - Finagle-Redis 5.3.1-SNAPSHOT
    - finagle, netty 3, naggati codec
    - 3.26 MB/s
    - 12,468 sps
  - redis-protocol/finagle 0.3-SNAPSHOT
    - finagle, netty 3, custom codec
    - 3.96 MB/s
    - 15,281 sps
  - redis-protocol/netty4 0.3-SNAPSHOT
    - netty 4, custom codec
    - 5.08 MB/s
    - 19,601 sps
  - redis-benchmark -n 1000000 -c 1 -r 1000000 set test test
    - C client included with distribution
    - 5.53 MB/s
    - 22,055 sps
  - JRedis a.0-SNAPSHOT
    - blocking i/o
    - 6.08 MB/s
    - 23,738 sps
  - Jedis 2.2.0-SNAPSHOT
    - blocking i/o
    - 6.11 MB/s
    - 24,001 sps
  - redis-protocol/finagle-service 0.3-SNAPSHOT
    - finagle, blocking i/o
    - 6.40 MB/s
    - 24,379 sps
  - redis-protocol/client 0.3-SNAPSHOT
    - blocking i/o
    - 6.72 MB/s
    - 25,795 sps


Copyright 2012 Sam Pullara

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

redis-protocol's People

Contributors

aslakhellesoy avatar fcarriedo avatar lbovet avatar spullara avatar yulin2 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

redis-protocol's Issues

error executing setnx in a pipeline

this is maybe also twemproxy related.

after the latest twemproxy related fixes i now get this error:

Exception in thread "main" redis.client.RedisException: Failed to execute: SETNX
    at redis.client.RedisClientBase.pipeline(RedisClientBase.java:149)
    at redis.client.RedisClient$Pipeline.setnx(RedisClient.java:3017)
...
Caused by: java.net.SocketException: Broken pipe
    at java.net.SocketOutputStream.socketWrite0(Native Method)
    at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
    at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
    at redis.RedisProtocol.sendAsync(RedisProtocol.java:185)
    at redis.client.RedisClientBase.pipeline(RedisClientBase.java:146)
    ... 9 more

I know this is not much info, any idea how i can find out what's really going on here?

Subscription dies on server reset with no reconnect or indication of failure

If a client is subscribed and the server is bounced, no attempt is made to resubscribe the client (and of course no Exception is thrown since the thread does not block on the subscribe call).

This can be reproduced by running the following test, putting a breakpoint on creation of client3 and bouncing the Redis server before continuing. "World" is not printed out.

    @Test
    public void testSubscribe() throws IOException {
        RedisClient client = new RedisClient("localhost", 6379);
        client.addListener(new SrpListener());
        client.subscribe("channel1".getBytes());
        RedisClient client2 = new RedisClient("localhost", 6379);
        client2.publish("channel1".getBytes(), "Hello".getBytes());
        RedisClient client3 = new RedisClient("localhost", 6379);
        client3.publish("channel1".getBytes(), "World".getBytes());
    }

    private class SrpListener implements ReplyListener {
        public void subscribed(byte[] name, int channels) {
        }

        public void psubscribed(byte[] name, int channels) {
        }

        public void unsubscribed(byte[] name, int channels) {
        }

        public void punsubscribed(byte[] name, int channels) {
        }

        public void message(byte[] channel, byte[] message) {
            System.out.println(new String(message));    
        }

        public void pmessage(byte[] pattern, byte[] channel, byte[] message) {
        }
    }

SocketPool shutdown option

Currently there's no option to close the opened sockets inside SocketPool which means unless the connections are all tracked, there might be opened sockets left behind after an application shuts down.

version error

My redis info:

redis_version:2.6.8-pre2
redis_git_sha1:00000000
redis_git_dirty:0
redis_mode:standalone
os:Windows
arch_bits:64
multiplexing_api:winsock_IOCP
gcc_version:0.0.0
process_id:2076
run_id:f0c885c82b3cc21d7780a7725171
tcp_port:6379
uptime_in_seconds:3233
uptime_in_days:0
lru_clock:1217859

error:
Exception in thread "main" redis.client.RedisException: Server does not support SET
at redis.client.RedisClient.set(RedisClient.java:359)
at redisTest.redisTest.RedisProtocolTest.main(RedisProtocolTest.java:12)

Exception not set for individual failures on exec

The following test results in a MultiBulkReply on exec, where one of the replies is an ErrorReply. This causes a return of a String with an error message instead of an Exception when the future is polled. Not having the exception set makes it difficult for our API to detect errors and respond appropriately.

    @Test
    public void testRestoreBadData() throws Exception {
        RedisClient client = new RedisClient("localhost", 6379);
        Pipeline pipeline = client.pipeline();
        client.multi();

        // Use something other than dump-specific serialization to cause an error on restore
        ListenableFuture restoreResults = pipeline.restore("testing".getBytes(), 0, "foo".getBytes());
        Future<Boolean> execResults = client.exec();
        assertTrue(execResults.get());

        // The result of restore is supposed to be a ListenableFuture<StatusReply>, which I can't cast
        // to ErrorReply. Should get() throw an Exception instead?
        ErrorReply reply = (ErrorReply) restoreResults.get();
        System.out.println(reply.data());   
    }

Exception on ZRANGEBYSCORE

The testsuite for solr-redis (https://github.com/sematext/solr-redis) yield the following exception on ZRANGEBYSCORE:

java.lang.IndexOutOfBoundsException: Index: 4, Size: 4
    at java.util.ArrayList.rangeCheck(ArrayList.java:635)
    at java.util.ArrayList.get(ArrayList.java:411)
    at redis.util.ZSet.subSet(ZSet.java:125)
    at redis.server.netty.SimpleRedisServer._zrangebyscore(SimpleRedisServer.java:2850)
    at redis.server.netty.SimpleRedisServer.zrevrangebyscore(SimpleRedisServer.java:3035)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at redis.server.netty.RedisCommandHandler$1.execute(RedisCommandHandler.java:44)
    at redis.server.netty.RedisCommandHandler.messageReceived(RedisCommandHandler.java:82)
    at redis.server.netty.RedisCommandHandler.messageReceived(RedisCommandHandler.java:25)
    at io.netty.channel.ChannelHandlerUtil.handleInboundBufferUpdated(ChannelHandlerUtil.java:60)
    at io.netty.channel.ChannelInboundMessageHandlerAdapter.inboundBufferUpdated(ChannelInboundMessageHandlerAdapter.java:100)
    at io.netty.channel.DefaultChannelHandlerContext.invokeInboundBufferUpdated(DefaultChannelHandlerContext.java:1031)
    at io.netty.channel.DefaultChannelHandlerContext.access$1500(DefaultChannelHandlerContext.java:39)
    at io.netty.channel.DefaultChannelHandlerContext$13.run(DefaultChannelHandlerContext.java:1005)
    at io.netty.util.concurrent.DefaultEventExecutor.run(DefaultEventExecutor.java:36)
    at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:114)
    at java.lang.Thread.run(Thread.java:745)
java.lang.IndexOutOfBoundsException: Index: 4, Size: 4
    at java.util.ArrayList.rangeCheck(ArrayList.java:635)
    at java.util.ArrayList.get(ArrayList.java:411)
    at redis.util.ZSet.subSet(ZSet.java:125)
    at redis.server.netty.SimpleRedisServer._zrangebyscore(SimpleRedisServer.java:2850)
    at redis.server.netty.SimpleRedisServer.zrevrangebyscore(SimpleRedisServer.java:3035)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at redis.server.netty.RedisCommandHandler$1.execute(RedisCommandHandler.java:44)
    at redis.server.netty.RedisCommandHandler.messageReceived(RedisCommandHandler.java:82)
    at redis.server.netty.RedisCommandHandler.messageReceived(RedisCommandHandler.java:25)
    at io.netty.channel.ChannelHandlerUtil.handleInboundBufferUpdated(ChannelHandlerUtil.java:60)
    at io.netty.channel.ChannelInboundMessageHandlerAdapter.inboundBufferUpdated(ChannelInboundMessageHandlerAdapter.java:100)
    at io.netty.channel.DefaultChannelHandlerContext.invokeInboundBufferUpdated(DefaultChannelHandlerContext.java:1031)
    at io.netty.channel.DefaultChannelHandlerContext.access$1500(DefaultChannelHandlerContext.java:39)
    at io.netty.channel.DefaultChannelHandlerContext$13.run(DefaultChannelHandlerContext.java:1005)
    at io.netty.util.concurrent.DefaultEventExecutor.run(DefaultEventExecutor.java:36)
    at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:114)
    at java.lang.Thread.run(Thread.java:745)

Embedding Redis

How would I startup the netty server embedded? Are there examples?

RedisClient's pipeline throw Exception when in concurrent mode

version:
com.github.spullara.redis
client
0.8-SNAPSHOT

test code:
private static final String ip = "192.168.152.128";
private static RedisClient rc = null;
private static final int port = 6379;
final static String value = new String(new byte[8]);
public static void main(String[] args) throws InterruptedException, IOException {
rc = new RedisClient(ip, port);
final AtomicLong i = new AtomicLong();
// concurrent no. is 500,total task is 100000
StressTestUtils.testAndPrint(500, 100000, new StressTask() {
@OverRide
public Object doTask() throws Exception {
Pipeline pipeline = rc.pipeline();
ListenableFuture set2 = pipeline.set("testMe_" + i.incrementAndGet(), value);
ListenableFuture sync = pipeline.sync();
Object result = sync.get().data();
//System.out.println(result);
return null;
}
});
}

exception:
11:33:31.390 [main] ERROR c.t.s.c.SimpleResultFormater - Test exception
java.util.concurrent.ExecutionException: java.io.IOException: Improper line ending: 42, 49
at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222) ~[na:1.6.0_37]
at java.util.concurrent.FutureTask.get(FutureTask.java:83) ~[na:1.6.0_37]
at com.gome.service.RedisProtocalTest$1.doTask(RedisProtocalTest.java:48) ~[classes/:na]
at com.taobao.stresstester.core.StressTester.warmUp(StressTester.java:46) [stresstester-1.0.jar:na]
at com.taobao.stresstester.core.StressTester.test(StressTester.java:63) [stresstester-1.0.jar:na]
at com.taobao.stresstester.core.StressTester.test(StressTester.java:55) [stresstester-1.0.jar:na]
at com.taobao.stresstester.StressTestUtils.test(StressTestUtils.java:19) [stresstester-1.0.jar:na]
at com.taobao.stresstester.StressTestUtils.testAndPrint(StressTestUtils.java:31) [stresstester-1.0.jar:na]
at com.taobao.stresstester.StressTestUtils.testAndPrint(StressTestUtils.java:27) [stresstester-1.0.jar:na]
at com.gome.service.RedisProtocalTest.main(RedisProtocalTest.java:39) [classes/:na]
java.io.IOException: Improper line ending: 42, 49
at redis.RedisProtocol.readBytes(RedisProtocol.java:88) ~[protocol-0.8-SNAPSHOT.jar:na]
at redis.RedisProtocol.receive(RedisProtocol.java:151) ~[protocol-0.8-SNAPSHOT.jar:na]
at redis.RedisProtocol.receiveAsync(RedisProtocol.java:174) ~[protocol-0.8-SNAPSHOT.jar:na]
at redis.client.RedisClientBase$2.call(RedisClientBase.java:181) ~[client-0.8-SNAPSHOT.jar:na]
at redis.client.RedisClientBase$2.call(RedisClientBase.java:1) ~[client-0.8-SNAPSHOT.jar:na]
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) ~[na:1.6.0_37]
at java.util.concurrent.FutureTask.run(FutureTask.java:138) ~[na:1.6.0_37]
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) ~[na:1.6.0_37]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) ~[na:1.6.0_37]
at java.lang.Thread.run(Thread.java:662) ~[na:1.6.0_37]
11:33:31.395 [main] ERROR c.t.s.c.SimpleResultFormater - Test exception
java.util.concurrent.ExecutionException: java.io.IOException: Unexpected character in stream: 10
at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222) ~[na:1.6.0_37]
at java.util.concurrent.FutureTask.get(FutureTask.java:83) ~[na:1.6.0_37]
at com.gome.service.RedisProtocalTest$1.doTask(RedisProtocalTest.java:48) ~[classes/:na]
at com.taobao.stresstester.core.StressTester.warmUp(StressTester.java:46) [stresstester-1.0.jar:na]
at com.taobao.stresstester.core.StressTester.test(StressTester.java:63) [stresstester-1.0.jar:na]
at com.taobao.stresstester.core.StressTester.test(StressTester.java:55) [stresstester-1.0.jar:na]
at com.taobao.stresstester.StressTestUtils.test(StressTestUtils.java:19) [stresstester-1.0.jar:na]
at com.taobao.stresstester.StressTestUtils.testAndPrint(StressTestUtils.java:31) [stresstester-1.0.jar:na]
at com.taobao.stresstester.StressTestUtils.testAndPrint(StressTestUtils.java:27) [stresstester-1.0.jar:na]
at com.gome.service.RedisProtocalTest.main(RedisProtocalTest.java:39) [classes/:na]

ClassCastException when exec returns an ErrorReply in Redis 2.6

The following test produces the following error when running against Redis 2.6 (using client-0.5)

@Test
public void testExecuteSyntaxError() throws IOException, InterruptedException, ExecutionException {
    RedisClient client = new RedisClient("localhost", 6379);
    client.multi();
    String name = "ZADD";
    // Wrong number of arguments for zadd command
    Command cmd = new Command(name.getBytes(Charsets.UTF_8),"foo");
    ListenableFuture<? extends Reply> f = client.pipeline(name, cmd);
    Future<Boolean> exec = client.exec();
    exec.get();
    f.get();
}

Error:

java.util.concurrent.ExecutionException: java.lang.ClassCastException: redis.reply.ErrorReply cannot be cast to redis.reply.MultiBulkReply
at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222)
at java.util.concurrent.FutureTask.get(FutureTask.java:83)
at org.springframework.data.redis.connection.srp.SrpTest.testExecuteSyntaxError(SrpTest.java:27)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.ClassCastException: redis.reply.ErrorReply cannot be cast to redis.reply.MultiBulkReply
at redis.client.RedisClientBase$3.call(RedisClientBase.java:238)
at redis.client.RedisClientBase$3.call(RedisClientBase.java:235)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:680)

redis.client.RedisException: ERR operation not permitted

when I run this line:

RedisClient redisClient = new RedisClient("50.30.35.9", 2774); // free hosted on http://redis4you.com for testing

I get this stack trace:

redis.client.RedisException: ERR operation not permitted
at redis.client.RedisClientBase.execute(RedisClientBase.java:162)
at redis.client.RedisClientBase.<init>(RedisClientBase.java:63)
at redis.client.RedisClient.<init>(RedisClient.java:23)

...

I wonder if it has to do with a required password? (requirepass 839617db07e03f59e96fe9564b730d2c)

script_exists only returns one result and it's false

Looks like script_exists is passing the script names in as an Object and not an Object[] when constructing Command. This is causing the script names array to be written out to Redis as a toString on the array instead of writing out the individual array elements. This always results in a single return value of "false".

test failure with redis redis 2.6.13

testExecuteSyntaxError(redis.client.Issue19Test)  Time elapsed: 0.017 sec
junit.framework.AssertionFailedError: null
    at junit.framework.Assert.fail(Assert.java:47)
    at junit.framework.Assert.assertTrue(Assert.java:20)
    at junit.framework.Assert.assertTrue(Assert.java:27)
    at redis.client.Issue19Test.testExecuteSyntaxError(Issue19Test.java:36)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)

cause.getMessage() returns "EXECABORT Transaction discarded because of previous errors."

pub/sub improvements

a. pmessage is not currently implemented (only message)
b. it's not possible to remove a ReplyListener (after it was registered).
c. a possible improvement to b), for misbehaved clients, would be to remove all listener once the connection closes or all the subscriptions (for channels and patterns) have been removed.

Replies never received after previous transaction discarded

In RedisClientBase.discard(), the txReplies queue is not cleared. This causes Reply gets to hang on next transaction. For example, testMultiDiscard hangs on the last line of testMultiExec:

private RedisClient client;

@Before
public void setUp() throws Exception {
    client = new RedisClient("localhost", 6379);
}

@Test
public void testMultiDiscard() throws Exception {
    client.set("testitnow", "willdo");
    client.multi();
    client.pipeline().set("testitnow", "notok");
    client.discard();
    assertEquals("willdo", new String(client.get("testitnow").data()));
    // Ensure we can run a new tx after discarding previous one
    testMultiExec();
}

@Test
public void testMultiExec() throws Exception {
    client.multi();
    ListenableFuture<StatusReply> reply = client.pipeline().set("key", "value");
    client.exec();
    assertEquals("OK",reply.get().data());
}

redis.netty.BulkReply cannot be cast to redis.netty.MultiBulkReply

Using netty-client, after many calls to hgetall I start getting ClassCastException. I call hgetall a lot, for the cases that fail I can query the key with redis-cli, it is there an has more than one field of data, should generate a MultiBulkReply. Not clear why I see responses that are not MultiBulkReply.

java.lang.ClassCastException: redis.netty.BulkReply cannot be cast to redis.netty.MultiBulkReply

net.connexity.actor.CCMSTMActor$$anon$1.apply(STMActor.scala:2035)
spullara.util.concurrent.Promise.set(Promise.java:86)
redis.netty.client.RedisClientBase$1.messageReceived(RedisClientBase.java:113)
org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:302)
org.jboss.netty.handler.codec.replay.ReplayingDecoder.unfoldAndFireMessageReceived(ReplayingDecoder.java:525)
org.jboss.netty.handler.codec.replay.ReplayingDecoder.callDecode(ReplayingDecoder.java:506)
org.jboss.netty.handler.codec.replay.ReplayingDecoder.messageReceived(ReplayingDecoder.java:443)
org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:274)
org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:261)
org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:349)
org.jboss.netty.channel.socket.nio.NioWorker.processSelectedKeys(NioWorker.java:280)
org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:200)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
java.lang.Thread.run(Thread.java:724)

raw bytes[] not supported (due to vararg wrapping)

Hi,

I took a first pass at integrating this project or as I call it SRP (Sam's Redis Protocol) into Spring Data Redis [1] and the biggest issue I encounter was the lack of support for passing raw byte[] to RedisClient. While the protocol supports this the use of varargs causes the passed byte[] to be wrapped in an Object[] which the protocol doesn't understand (and thus calls toString() on it).

The problem lies within the use of varargs between various methods and RedisClientBase#pipeline method.

Take mget - if you pass a byte[] it will gets wrapped in an Object[] automatically (Object[] {byte[]}) which
For all commands RedisClient calls pipeline(CMD, CMD_as bytes, arguments) which get wrapped into an Object[] that gets sent to redisProtocol#sendAsync and further down to Command#writeDirect().
At this point Command receives Object[] { CMD as bytes, Object[] { byte[] } } - it knows how to handle CMD but it doesn't unwrap the Object[] and instead calls toString() on it.
A simple fix would be to check for this wrapper or avoid it in the first place.

[1] https://github.com/SpringSource/spring-data-redis/tree/srp

netty-client does not work with newer netty

It seems the netty-client only works with netty up to version 3.5.6. All newer versions just block on the connect call. If I change the netty dependency to 3.6.2 or 3.5.12 the test suite just hangs.

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running redis.netty.client.RedisClientBaseTest
Completed 0 per second
Completed 0 per second
Completed 0 per second

pluggable ExecutorService in RedisClientBase

It would be helpful to be able to control the threads used internally by RedisClientBase (think managed environments) - especially when dealing with a lot of clients or app servers - could you expose es through the constructor or a setter (or avoid shutting it down when initialized externally?).

Cheers

Blocking operation doesn't return even though the client has been closed

My test is:
Create a child thread and it do BRPOPLPUSH for blocking itself to wait for data from redis, and then close the redis client(close the socket InputStream and OutputStream) in main thread, suppose the child thread should return by IOException throwing, but it is still blocked and it never returns until any reponse is received from redis.

HMGET.asStringList returns less answers than requested

Redis "struct" HASH content:
"field1" = "1"
// "field2" is missing

Java code:

List<String> rec = client.hmget("struct", "field1", "field2").asStringList(Charsets.UTF_8);

Returns only one String... but you don't know which one :(
It makes HMGET function useless, because you can't match requested field with returned values.

Only one workaround is to analyse MultiBulkReply.data[] and manually match fields by request index.

IntegerReply/ErrorReply cannot be cast to MultiBulkReply

Caused by: java.lang.ClassCastException: redis.reply.ErrorReply cannot be cast to redis.reply.MultiBulkReply
at redis.client.RedisClient.zrange(RedisClient.java:1349)
at org.springframework.data.redis.connection.srp.SrpConnection.zRange(SrpConnection.java:1328)
... 42 more

meaning
return (MultiBulkReply) execute(ZRANGE, new Command(ZRANGE_BYTES, list.toArray(new Object[list.size()])))

Caused by: java.lang.ClassCastException: redis.reply.BulkReply cannot be cast to redis.reply.IntegerReply
at redis.client.RedisClient.zrank(RedisClient.java:1375)
at org.springframework.data.redis.connection.srp.SrpConnection.zRank(SrpConnection.java:1471)
... 42 more

ClassCastException on brpoplpush timeout

Calling brpoplpush on an empty source list results in a ClassCastException.

RedisClient client = new RedisClient("localhost", 6379);
client.brpoplpush("alist", "foo", 1);

java.lang.ClassCastException: redis.reply.MultiBulkReply cannot be cast to redis.reply.BulkReply
at redis.client.RedisClient.brpoplpush(RedisClient.java:967)
at org.springframework.data.redis.connection.srp.SrpTest.testBrPopLPushTimeout(SrpTest.java:82)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

Generate tests from redis.io

It should be possible to parse and generate tests from the examples on redis.io. Comparisons can be made with a local redis server.

redis.reply.MultiBulkReply cannot be cast to redis.reply.BulkReply

The command brpoplpush, if timeout reached, redis server returns a MultiBulkReply instead of BulkReply.

public BulkReply brpoplpush(Object source0, Object destination1, Object timeout2) throws RedisException {
    if (version < BRPOPLPUSH_VERSION) throw new RedisException("Server does not support BRPOPLPUSH");
    return (BulkReply) execute(BRPOPLPUSH, new Command(BRPOPLPUSH_BYTES, source0, destination1, timeout2));
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.