spullara / redis-protocol Goto Github PK
View Code? Open in Web Editor NEWJava client and server implementation of Redis
Java client and server implementation of Redis
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.
Curious if the redis benchmark code you have is written to test the java based server you have (I know it isn't complete) or is it really testing the java based redis client that connects to a redis server (the original, c based one).
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?
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) {
}
}
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.
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)
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());
}
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)
How would I startup the netty server embedded? Are there examples?
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]
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)
zrangebyscore redis method supports opened ranges: http://redis.io/commands/zrevrangebyscore
ZREVRANGEBYSCORE myzset (2 (1
Java redis protocol doesn't support that.
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)
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".
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."
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.
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());
}
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)
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
It seems this client does not work with twemproxy
https://github.com/twitter/twemproxy
I have no idea why that's the case, does the client maybe always use a pipeline? (twemproxy does not support pipelining)
Seems the bit operations are not supported:
http://redis.io/commands/bitcount
http://redis.io/commands/bitop
Hi,
I didn't find how to do INFO + with redis-protocol.
Could you show me how to do?
Thanks
Regards,
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
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
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.
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.
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
Not available LICENSE file in source directory structure
Please. Added license and copyright notice.
the fedora pakaging guideline is very strictly precise about this problem
https://fedoraproject.org/wiki/Packaging:LicensingGuidelines?rd=Packaging/LicensingGuidelines#License_Text
thanks
regards
N/A
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)
It should be possible to parse and generate tests from the examples on redis.io. Comparisons can be made with a local redis server.
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));
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.