redis / lettuce Goto Github PK
View Code? Open in Web Editor NEWAdvanced Java Redis client for thread-safe sync, async, and reactive usage. Supports Cluster, Sentinel, Pipelining, and codecs.
Home Page: https://lettuce.io
License: MIT License
Advanced Java Redis client for thread-safe sync, async, and reactive usage. Supports Cluster, Sentinel, Pipelining, and codecs.
Home Page: https://lettuce.io
License: MIT License
RedisPubSubConnectionImpl
re-subscribes to patterns and channels on reconnects but these futures are not accessible. Adding a protected List<RedisFuture<Void>> resubscribe()
will allow accessing these futures.
my code:
public static void main(String[] args) throws Exception {
final RedisConnection<String, byte[]> sync = new RedisClient("10.58.52.60", 5021)
.connect(new BytesCodec());
sync.flushall();
final CountDownLatch c = new CountDownLatch(1);
new Thread(new Runnable() {
public void run() {
try {
c.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sync.multi();
sync.set("a", Thread.currentThread().getName().getBytes());
sync.set("a1", Thread.currentThread().getName().getBytes());
System.out.println(1234);
}
}).start();
new Thread(new Runnable() {
public void run() {
try {
c.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
sync.multi();
sync.set("a", Thread.currentThread().getName().getBytes());
sync.set("a1", Thread.currentThread().getName().getBytes());
sync.exec();
System.out.println(5678);
}
}).start();
c.countDown();
}
output:
Exception in thread "Thread-2" com.lambdaworks.redis.RedisCommandExecutionException: ERR MULTI calls can not be nested
at com.lambdaworks.redis.LettuceFutures.await(LettuceFutures.java:76)
at com.lambdaworks.redis.FutureSyncInvocationHandler.handleInvocation(FutureSyncInvocationHandler.java:59)
at com.google.common.reflect.AbstractInvocationHandler.invoke(AbstractInvocationHandler.java:87)
at $Proxy5.multi(Unknown Source)
at com.lambdaworks.redis.AsyncConnectionConcurrentTest$2.run(AsyncConnectionConcurrentTest.java:44)
at java.lang.Thread.run(Thread.java:662)
1234
Commands can be created with null outputs. I think this could be cleaned up to require non-null Outputs. I think we should also remove the setOutput() call on command as well. Output is used in the RedisStateMachine, and changing output midstream or having a missing one can lead to issues.
From an initial look, only 2 commands have no output. The debugOOM and debugSegfault. Both these kill the server, so there is no output to report. I wasn't able to find any other places where a null output is used.
If this seems OK, I'd like to go down this path.
Also, is this the best way to discuss code proposals like this?
The following code works for a while but stops receiving messages very quickly. When run without the debugger, I actually get the following error messages:
15/01/09 21:36:50 WARN channel.DefaultChannelPipeline: An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
java.lang.OutOfMemoryError: Java heap space
To expedite the process I limit JVM memory with -Xmx32m
. However, I first discovered this issue while running a production server with 6GB heap size. It was under very low load and received a small message every 20 seconds. At some point I noticed messages were not being delivered anymore and the logs threw the same OOM errors. A heap dump showed buffer
in com.lambdaworks.redis.protocol.CommanHandler
was a holding a contiguous 1GB array. It was trying to extend the buffer, but had no more huge contiguous blocks in the heap.
I am weirdly unable to reproduce the OOM in a debugger. However, when running in a debugger, I still do get the same issue with messages not being received after a while.
import java.util.Arrays;
import java.util.concurrent.ExecutionException;
import java.util.logging.Logger;
import com.lambdaworks.redis.RedisClient;
import com.lambdaworks.redis.RedisConnection;
import com.lambdaworks.redis.RedisURI;
import com.lambdaworks.redis.codec.Utf8StringCodec;
import com.lambdaworks.redis.pubsub.RedisPubSubConnectionImpl;
import com.lambdaworks.redis.pubsub.RedisPubSubListener;
public class LettuceMemoryLeak implements RedisPubSubListener<String, String>
{
private static Logger LOGGER = Logger.getLogger( "LettuceMemoryLeak" );
public static void main( String[] args ) throws InterruptedException, ExecutionException
{
RedisURI uri = RedisURI.Builder.sentinel( "localhost", 26379, "mymaster" ).build();
RedisClient client = new RedisClient( uri );
RedisPubSubConnectionImpl<String, String> subscriber = client.connectPubSub( new Utf8StringCodec() );
subscriber.subscribe( "test" );
subscriber.addListener( new LettuceMemoryLeak() );
RedisConnection<String, String> publisher = client.connect( new Utf8StringCodec() );
char[] chars = new char[8096];
Arrays.fill( chars, 'a' );
String str = new String( chars );
while( true ) {
publisher.publish( "test", str );
}
}
@Override
public void message( String channel, String message )
{
LOGGER.info( channel );
}
@Override
public void message( String pattern, String channel, String message )
{
}
@Override
public void subscribed( String channel, long count )
{
LOGGER.info( "subscribed to " + channel + " " + count );
}
@Override
public void psubscribed( String pattern, long count )
{
}
@Override
public void unsubscribed( String channel, long count )
{
}
@Override
public void punsubscribed( String pattern, long count )
{
}
}
I'll update this ticket once I have more information.
See http://redis.io/commands/command for details
hvals (streaming)
migrate
mget (streaming)
sdiff (streaming)
sinter (streaming)
smembers (streaming)
sort (streaming)
srandmember (streaming)
wait
zrange (streaming)
zrangeWithScores
zrangebyscore
zrangebyscoreWithScores
zrevrange
zrevrangeWithScores
zrevrangebyscore
zrevrangebyscoreWithScores
scan (streaming)
sscan (streaming)
hscan (streaming)
zscan (streaming)
Use JDK8 for build but still support Java 6 and 7. Depends on JavaDoc compatibility with Java 8 #39 and requires to have a test project in order to ensure lettuce usage on JDK6/7/8
java.lang.NullPointerException
at com.lambdaworks.redis.output.MultiOutput.set(MultiOutput.java:48)
at com.lambdaworks.redis.output.MultiOutput.set(MultiOutput.java:48)
at com.lambdaworks.redis.protocol.RedisStateMachine.decode(RedisStateMachine.java:108)
at com.lambdaworks.redis.protocol.CommandHandler.decode(CommandHandler.java:101)
at com.lambdaworks.redis.protocol.CommandHandler.channelRead(CommandHandler.java:89)
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:341)
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:327)
at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:341)
Add another layer between command creation and execution (today a command is created and immediately executed). Reactive commands should be only executed (example from RxJava as soon as call
is invoked).
This layer could be located between the command builder and the async connection itself.
See http://redis.io/commands/cluster-slots for details
Arguments to redis commands are currently not checked at all. Empty arrays, empty values (SLAVEOF, CLIENT KILL) and null values in arrays can be passed to redis
isOpen
to sentinel connectionclusterSlaves
on sync cluster connection interfacessyncHandler
in AbstractRedisClient
Generic exceptions (i.e. protocol exceptions, exceptions on callback to pubsub notifications) can lead to a defective internal state. It might be worth to provide a reconnect-on-exception functionality. This ticket needs further investigation and was opened due to #21
Return RedisFuture on methods:
When using core JDK8 features (mostly async) parts Java 6 and 7 support will be dropped.
ZADD options (Redis 3.0.2 or greater)
ZADD supports a list of options, specified after the name of the key and before the first score argument. Options are:
Add new ClientOptions
type at AbstractRedisClient
level (something like AbstractRedisClient#options()
) to control:
false
)true
)false
)Need input on this topic. The current RedisFuture
is a limited facility in terms of async. The underlying ListenableFuture
provides a very basic functionality. Chaining and promises are hard to achieve.
The internal state machine could run into an invalid state due to network failures, VM errors or unexpected/faulty Redis responses (i.e. version does not fit the Redis client).
This could be handled by closing the connection and reconnecting for getting a clear and defined state without any "backlog" on the TCP connection.
Inspect heavy load use cases using lettuce with YourKit to find hotspots to reduce latency
Some scenarios and users need to alter behavior of the redis client (see #31). This is currently not possible. It's required therefore to be able to extend the client and inject custom behavior.
This can be implemented by subclassing RedisClient and providing own implementations of the Redis...ConnectionImpl classes.
Methods:
clusterAddSlots
clusterDelSlots
clusterSetSlotNode
clusterSetSlotMigrating
clusterSetSlotImporting
clusterFlushslots
clusterFailover
clusteReset
Commands can run into a "won't ever come back" state when lettuce tries to reconnect but fails while reconnecting/re-issuing commands.
Desired behavior:
Either re-issue/retry commands on each reconnect or cancel commands after the reconnect failed but not loose commands.
See #31 (comment) for details
@Kitchik: Will continue parts of #31 here. What do you think about the desired behavior?
See http://redis.io/commands/role for details
Provide access to cluster connections with using an advanced cluster API
RedisAdvancedClusterConnection
and RedisAdvancedClusterAsyncConnection
Methods on RedisAdvancedClusterConnection
:
RedisClusterConnection getConnection(String nodeId)
RedisClusterConnection getConnection(String host, int port)
and Methods on RedisAdvancedClusterAsyncConnection
RedisClusterAsyncConnection getConnection(String nodeId)
RedisClusterAsyncConnection getConnection(String host, int port)
Use an improved calculation.
The CRC16 is specified as follows:
Current signature is: List<ScoredValue<ScoredValue<V>>>
should be List<ScoredValue<V>>
3.x code:
RedisConnection connection = client.connect();
4.x code:
StatefulRedisConnection stateful = client.connect();
RedisConnection connection = stateful.sync();
The other connect
methods like connectAsync
and connectSentinelAsync
will remain unchanged.
Affected connect
methods are:
RedisClient.connect
(provides a StatefulRedisConnection
)RedisClient.connectPubSub
(provides a StatefulRedisPubSubConnection
)RedisClusterClient.connect
(provides a StatefulRedisClusterConnection
)New connect methods:
RedisClient.connectSentinel
(provides a StatefulRedisSentinelConnection
)Provide @FunctionalInterface
on
See http://redis.io/commands/command-getkeys
Conception needed, since COMMAND GETKEYS is applicable with every command.
Tests fail due to missing implementation of MapOutput.setInteger. Adjust map value datatype for PUBSUB NUMSUB
command to Long.
java.lang.IllegalStateException
at com.lambdaworks.redis.protocol.CommandOutput.set(CommandOutput.java:60)
at com.lambdaworks.redis.protocol.RedisStateMachine.decode(RedisStateMachine.java:121)
at com.lambdaworks.redis.protocol.CommandHandler.decode(CommandHandler.java:101)
at com.lambdaworks.redis.protocol.CommandHandler.channelRead(CommandHandler.java:89)
Connection activation, after reconnects, causes in RedisPubSubConnectionImpl
to connect to the default database with no login, even if a previous login was performed. This is, because RedisPubSubConnectionImpl.activated
does not call super.activated()
Having an option to connect to a local Redis via UDS would be nice to have. It's allegedly faster.
From: http://redis.io/topics/benchmarks
Depending on the platform, unix domain sockets can achieve around 50% more throughput than the TCP/IP loopback (on Linux for instance)
Netty supports UDS in 4.0.26
https://twitter.com/normanmaurer/status/573090616000843777
Additional info from chat
mostly adding a new schemes to RedisURI, say redis-socket and redis-sentinel-socket or something like that then upgrading to latest netty, adding the socket resolution and maybe some bootstrap options.
Method connectPubSub
returns type RedisPubSubConnectionImpl
(class), should return RedisPubSubConnection
(interface)
RedisPubSubConnectionImpl.activated()
can deadlock if another thread is trying to subscribe or unsubscribe at the same time. RedisPubSubConnectionImpl.subscribe()
calls RedisAsyncConnectionImpl.dispatch()
which is synchronized. RedisAsyncConnectionImpl.dispatch()
calls CommandHandler.write()
which tries to get writeLock
. CommandHandler.channelActive()
holds writeLock
and calls RedisPubSubConnectionImpl.activated()
which calls RedisPubSubConnectionImpl.subscribe()
and tries to get the object lock held by the other thread trying to subscribe.
So basically:
CommandHandler.channelActive()
holds writeLock
and tries to get RedisAsyncConnectionImpl
object lockRedisPubSubConnectionImpl.subscribe()
holds RedisAsyncConnectionImpl
object lock and then tries to get writeLock
Consider using RxJava and Observable for async API. Current async API is not composable and prone to errors
Implement SSL support to connect to redis running behind a stunnel
Rework JavaDocs for Java8 compatibility:
[ERROR] Exit code: 1 - javadoc: warning - Error fetching URL: http://netty.io/4.0/api
[ERROR] javadoc: warning - Error fetching URL: http://commons.apache.org/proper/commons-pool/api-2.2
[ERROR] javadoc: warning - Error fetching URL: http://docs.guava-libraries.googlecode.com/git/javadoc
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/codec/CRC16.java:48: warning: no description for @param
[ERROR] * @param bytes
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/AbstractRedisClient.java:216: error: unterminated inline tag
[ERROR] * @param listener must not be {@literal null
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/BaseRedisAsyncConnection.java:47: warning: no description for @param
[ERROR] * @param channels
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/BaseRedisAsyncConnection.java:92: warning: no description for @param
[ERROR] * @param script
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/BaseRedisAsyncConnection.java:139: warning: no description for @param
[ERROR] * @param replicas
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/BaseRedisAsyncConnection.java:140: warning: no description for @param
[ERROR] * @param timeout
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/BaseRedisConnection.java:46: warning: no description for @param
[ERROR] * @param channels
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/BaseRedisConnection.java:69: error: semicolon missing
[ERROR] * @return List<Object> array-reply where the first element is one of master, slave, sentinel and the additional
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/BaseRedisConnection.java:91: warning: no description for @param
[ERROR] * @param script
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/BaseRedisConnection.java:137: warning: no description for @param
[ERROR] * @param replicas
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/BaseRedisConnection.java:138: warning: no description for @param
[ERROR] * @param timeout
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/ScanCursor.java:24: warning: no description for @param
[ERROR] * @param cursor
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/ScanCursor.java:45: warning: no description for @param
[ERROR] * @param cursor
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/KeyValue.java:18: warning: no description for @param
[ERROR] * @param key
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/KeyValue.java:19: warning: no description for @param
[ERROR] * @param value
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/LettuceFutures.java:65: warning: no @param for <K>
[ERROR] public static <K, V, T> T await(RedisCommand<K, V, T> cmd, long timeout, TimeUnit unit) {
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/LettuceFutures.java:65: warning: no @param for <V>
[ERROR] public static <K, V, T> T await(RedisCommand<K, V, T> cmd, long timeout, TimeUnit unit) {
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/LettuceFutures.java:65: warning: no @param for <T>
[ERROR] public static <K, V, T> T await(RedisCommand<K, V, T> cmd, long timeout, TimeUnit unit) {
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/LettuceStrings.java:4: error: bad use of '>'
[ERROR] * @author <a href="mailto:[email protected]">Mark Paluch</a>>
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisAsyncConnection.java:21: warning: no description for @param
[ERROR] * @param timeout
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisAsyncConnection.java:22: warning: no description for @param
[ERROR] * @param unit
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisAsyncConnection.java:29: warning: no description for @param
[ERROR] * @param db
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisAsyncConnection.java:37: warning: no description for @param
[ERROR] * @param password
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisHashesAsyncConnection.java:196: warning: no @param for key
[ERROR] RedisFuture<MapScanCursor<K, V>> hscan(K key);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisHashesAsyncConnection.java:196: warning: no @return
[ERROR] RedisFuture<MapScanCursor<K, V>> hscan(K key);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisHashesAsyncConnection.java:201: warning: no @param for key
[ERROR] RedisFuture<MapScanCursor<K, V>> hscan(K key, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisHashesAsyncConnection.java:201: warning: no @param for scanArgs
[ERROR] RedisFuture<MapScanCursor<K, V>> hscan(K key, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisHashesAsyncConnection.java:201: warning: no @return
[ERROR] RedisFuture<MapScanCursor<K, V>> hscan(K key, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisHashesAsyncConnection.java:206: warning: no @param for key
[ERROR] RedisFuture<MapScanCursor<K, V>> hscan(K key, ScanCursor scanCursor, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisHashesAsyncConnection.java:206: warning: no @param for scanCursor
[ERROR] RedisFuture<MapScanCursor<K, V>> hscan(K key, ScanCursor scanCursor, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisHashesAsyncConnection.java:206: warning: no @param for scanArgs
[ERROR] RedisFuture<MapScanCursor<K, V>> hscan(K key, ScanCursor scanCursor, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisHashesAsyncConnection.java:206: warning: no @return
[ERROR] RedisFuture<MapScanCursor<K, V>> hscan(K key, ScanCursor scanCursor, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisHashesAsyncConnection.java:211: warning: no @param for key
[ERROR] RedisFuture<MapScanCursor<K, V>> hscan(K key, ScanCursor scanCursor);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisHashesAsyncConnection.java:211: warning: no @param for scanCursor
[ERROR] RedisFuture<MapScanCursor<K, V>> hscan(K key, ScanCursor scanCursor);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisHashesAsyncConnection.java:211: warning: no @return
[ERROR] RedisFuture<MapScanCursor<K, V>> hscan(K key, ScanCursor scanCursor);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisHashesAsyncConnection.java:216: warning: no @param for channel
[ERROR] RedisFuture<StreamScanCursor> hscan(KeyValueStreamingChannel<K, V> channel, K key);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisHashesAsyncConnection.java:216: warning: no @param for key
[ERROR] RedisFuture<StreamScanCursor> hscan(KeyValueStreamingChannel<K, V> channel, K key);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisHashesAsyncConnection.java:216: warning: no @return
[ERROR] RedisFuture<StreamScanCursor> hscan(KeyValueStreamingChannel<K, V> channel, K key);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisHashesAsyncConnection.java:221: warning: no @param for channel
[ERROR] RedisFuture<StreamScanCursor> hscan(KeyValueStreamingChannel<K, V> channel, K key, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisHashesAsyncConnection.java:221: warning: no @param for key
[ERROR] RedisFuture<StreamScanCursor> hscan(KeyValueStreamingChannel<K, V> channel, K key, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisHashesAsyncConnection.java:221: warning: no @param for scanArgs
[ERROR] RedisFuture<StreamScanCursor> hscan(KeyValueStreamingChannel<K, V> channel, K key, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisHashesAsyncConnection.java:221: warning: no @return
[ERROR] RedisFuture<StreamScanCursor> hscan(KeyValueStreamingChannel<K, V> channel, K key, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisHashesAsyncConnection.java:231: warning: no @return
[ERROR] RedisFuture<StreamScanCursor> hscan(KeyValueStreamingChannel<K, V> channel, K key, ScanCursor scanCursor, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisHashesAsyncConnection.java:236: warning: no @param for channel
[ERROR] RedisFuture<StreamScanCursor> hscan(KeyValueStreamingChannel<K, V> channel, K key, ScanCursor scanCursor);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisHashesAsyncConnection.java:236: warning: no @param for key
[ERROR] RedisFuture<StreamScanCursor> hscan(KeyValueStreamingChannel<K, V> channel, K key, ScanCursor scanCursor);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisHashesAsyncConnection.java:236: warning: no @param for scanCursor
[ERROR] RedisFuture<StreamScanCursor> hscan(KeyValueStreamingChannel<K, V> channel, K key, ScanCursor scanCursor);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisHashesAsyncConnection.java:236: warning: no @return
[ERROR] RedisFuture<StreamScanCursor> hscan(KeyValueStreamingChannel<K, V> channel, K key, ScanCursor scanCursor);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:132: warning: no description for @param
[ERROR] * @param key
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:140: warning: no description for @param
[ERROR] * @param key
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:244: warning: no @param for key
[ERROR] RedisFuture<List<V>> sort(K key);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:251: warning: no @param for channel
[ERROR] RedisFuture<Long> sort(ValueStreamingChannel<V> channel, K key);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:251: warning: no @param for key
[ERROR] RedisFuture<Long> sort(ValueStreamingChannel<V> channel, K key);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:258: warning: no @param for key
[ERROR] RedisFuture<List<V>> sort(K key, SortArgs sortArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:258: warning: no @param for sortArgs
[ERROR] RedisFuture<List<V>> sort(K key, SortArgs sortArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:265: warning: no @param for channel
[ERROR] RedisFuture<Long> sort(ValueStreamingChannel<V> channel, K key, SortArgs sortArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:265: warning: no @param for key
[ERROR] RedisFuture<Long> sort(ValueStreamingChannel<V> channel, K key, SortArgs sortArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:265: warning: no @param for sortArgs
[ERROR] RedisFuture<Long> sort(ValueStreamingChannel<V> channel, K key, SortArgs sortArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:290: warning: no @return
[ERROR] RedisFuture<KeyScanCursor<K>> scan();
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:295: warning: no @param for scanArgs
[ERROR] RedisFuture<KeyScanCursor<K>> scan(ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:295: warning: no @return
[ERROR] RedisFuture<KeyScanCursor<K>> scan(ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:300: warning: no @param for scanCursor
[ERROR] RedisFuture<KeyScanCursor<K>> scan(ScanCursor scanCursor, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:300: warning: no @param for scanArgs
[ERROR] RedisFuture<KeyScanCursor<K>> scan(ScanCursor scanCursor, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:300: warning: no @return
[ERROR] RedisFuture<KeyScanCursor<K>> scan(ScanCursor scanCursor, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:305: warning: no @param for scanCursor
[ERROR] RedisFuture<KeyScanCursor<K>> scan(ScanCursor scanCursor);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:305: warning: no @return
[ERROR] RedisFuture<KeyScanCursor<K>> scan(ScanCursor scanCursor);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:310: warning: no @param for channel
[ERROR] RedisFuture<StreamScanCursor> scan(KeyStreamingChannel<K> channel);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:310: warning: no @return
[ERROR] RedisFuture<StreamScanCursor> scan(KeyStreamingChannel<K> channel);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:315: warning: no @param for channel
[ERROR] RedisFuture<StreamScanCursor> scan(KeyStreamingChannel<K> channel, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:315: warning: no @param for scanArgs
[ERROR] RedisFuture<StreamScanCursor> scan(KeyStreamingChannel<K> channel, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:315: warning: no @return
[ERROR] RedisFuture<StreamScanCursor> scan(KeyStreamingChannel<K> channel, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:320: warning: no description for @param
[ERROR] * @param channel
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:322: warning: no description for @param
[ERROR] * @param scanArgs
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:324: warning: no @return
[ERROR] RedisFuture<StreamScanCursor> scan(KeyStreamingChannel<K> channel, ScanCursor scanCursor, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:329: warning: no @param for channel
[ERROR] RedisFuture<StreamScanCursor> scan(KeyStreamingChannel<K> channel, ScanCursor scanCursor);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:329: warning: no @param for scanCursor
[ERROR] RedisFuture<StreamScanCursor> scan(KeyStreamingChannel<K> channel, ScanCursor scanCursor);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisKeysAsyncConnection.java:329: warning: no @return
[ERROR] RedisFuture<StreamScanCursor> scan(KeyStreamingChannel<K> channel, ScanCursor scanCursor);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisSetsAsyncConnection.java:208: warning: no @param for key
[ERROR] RedisFuture<ValueScanCursor<V>> sscan(K key);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisSetsAsyncConnection.java:208: warning: no @return
[ERROR] RedisFuture<ValueScanCursor<V>> sscan(K key);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisSetsAsyncConnection.java:213: warning: no @param for key
[ERROR] RedisFuture<ValueScanCursor<V>> sscan(K key, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisSetsAsyncConnection.java:213: warning: no @param for scanArgs
[ERROR] RedisFuture<ValueScanCursor<V>> sscan(K key, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisSetsAsyncConnection.java:213: warning: no @return
[ERROR] RedisFuture<ValueScanCursor<V>> sscan(K key, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisSetsAsyncConnection.java:218: warning: no @param for key
[ERROR] RedisFuture<ValueScanCursor<V>> sscan(K key, ScanCursor scanCursor, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisSetsAsyncConnection.java:218: warning: no @param for scanCursor
[ERROR] RedisFuture<ValueScanCursor<V>> sscan(K key, ScanCursor scanCursor, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisSetsAsyncConnection.java:218: warning: no @param for scanArgs
[ERROR] RedisFuture<ValueScanCursor<V>> sscan(K key, ScanCursor scanCursor, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisSetsAsyncConnection.java:218: warning: no @return
[ERROR] RedisFuture<ValueScanCursor<V>> sscan(K key, ScanCursor scanCursor, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisSetsAsyncConnection.java:223: warning: no @param for key
[ERROR] RedisFuture<ValueScanCursor<V>> sscan(K key, ScanCursor scanCursor);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisSetsAsyncConnection.java:223: warning: no @param for scanCursor
[ERROR] RedisFuture<ValueScanCursor<V>> sscan(K key, ScanCursor scanCursor);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisSetsAsyncConnection.java:223: warning: no @return
[ERROR] RedisFuture<ValueScanCursor<V>> sscan(K key, ScanCursor scanCursor);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisSetsAsyncConnection.java:228: warning: no @param for channel
[ERROR] RedisFuture<StreamScanCursor> sscan(ValueStreamingChannel<V> channel, K key);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisSetsAsyncConnection.java:228: warning: no @param for key
[ERROR] RedisFuture<StreamScanCursor> sscan(ValueStreamingChannel<V> channel, K key);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisSetsAsyncConnection.java:228: warning: no @return
[ERROR] RedisFuture<StreamScanCursor> sscan(ValueStreamingChannel<V> channel, K key);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisSetsAsyncConnection.java:233: warning: no @param for channel
[ERROR] RedisFuture<StreamScanCursor> sscan(ValueStreamingChannel<V> channel, K key, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisSetsAsyncConnection.java:233: warning: no @param for key
[ERROR] RedisFuture<StreamScanCursor> sscan(ValueStreamingChannel<V> channel, K key, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisSetsAsyncConnection.java:233: warning: no @param for scanArgs
[ERROR] RedisFuture<StreamScanCursor> sscan(ValueStreamingChannel<V> channel, K key, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisSetsAsyncConnection.java:233: warning: no @return
[ERROR] RedisFuture<StreamScanCursor> sscan(ValueStreamingChannel<V> channel, K key, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisSetsAsyncConnection.java:238: warning: no description for @param
[ERROR] * @param channel
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisSetsAsyncConnection.java:241: warning: no description for @param
[ERROR] * @param scanArgs
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisSetsAsyncConnection.java:243: warning: no @return
[ERROR] RedisFuture<StreamScanCursor> sscan(ValueStreamingChannel<V> channel, K key, ScanCursor scanCursor, ScanArgs scanArgs);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisSetsAsyncConnection.java:248: warning: no @param for channel
[ERROR] RedisFuture<StreamScanCursor> sscan(ValueStreamingChannel<V> channel, K key, ScanCursor scanCursor);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisSetsAsyncConnection.java:248: warning: no @param for key
[ERROR] RedisFuture<StreamScanCursor> sscan(ValueStreamingChannel<V> channel, K key, ScanCursor scanCursor);
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisChannelHandler.java:158: error: malformed HTML
[ERROR] * @return RedisChannelWriter<K, V>
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisChannelHandler.java:158: error: bad use of '>'
[ERROR] * @return RedisChannelWriter<K, V>
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisChannelWriter.java:21: error: malformed HTML
[ERROR] * @return RedisCommand<K, V, T>
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisChannelWriter.java:21: error: bad use of '>'
[ERROR] * @return RedisCommand<K, V, T>
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisClient.java:111: error: malformed HTML
[ERROR] * @return RedisConnectionPool<RedisConnection<K, V>>
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisClient.java:111: error: malformed HTML
[ERROR] * @return RedisConnectionPool<RedisConnection<K, V>>
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisClient.java:111: error: bad use of '>'
[ERROR] * @return RedisConnectionPool<RedisConnection<K, V>>
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisClient.java:111: error: bad use of '>'
[ERROR] * @return RedisConnectionPool<RedisConnection<K, V>>
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisListsConnection.java:22: error: malformed HTML
[ERROR] * @return KeyValue<K,V> array-reply specifically:
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisListsConnection.java:22: error: bad use of '>'
[ERROR] * @return KeyValue<K,V> array-reply specifically:
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisListsConnection.java:35: error: malformed HTML
[ERROR] * @return KeyValue<K,V> array-reply specifically:
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/RedisListsConnection.java:35: error: bad use of '>'
[ERROR] * @return KeyValue<K,V> array-reply specifically:
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/ScriptOutputType.java:13: error: text not allowed in <ul> element
[ERROR] * <li>{@link #MULTI} of these types</li>.
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/ScriptOutputType.java:20: error: bad use of '>'
[ERROR] * <li>Redis integer reply -> Lua number</li>
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/ScriptOutputType.java:21: error: bad use of '>'
[ERROR] * <li>Redis bulk reply -> Lua string</li>
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/ScriptOutputType.java:22: error: bad use of '>'
[ERROR] * <li>Redis multi bulk reply -> Lua table (may have other Redis data types nested)</li>
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/ScriptOutputType.java:23: error: bad use of '>'
[ERROR] * <li>Redis status reply -> Lua table with a single <code>ok</code> field containing the status</li>
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/ScriptOutputType.java:24: error: bad use of '>'
[ERROR] * <li>Redis error reply -> Lua table with a single <code>err</code> field containing the error</li>
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/ScriptOutputType.java:25: error: bad use of '>'
[ERROR] * <li>Redis Nil bulk reply and Nil multi bulk reply -> Lua false boolean type</li>
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/ScriptOutputType.java:31: error: bad use of '>'
[ERROR] * <li>Lua number -> Redis integer reply (the number is converted into an integer)</li>
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/ScriptOutputType.java:32: error: bad use of '>'
[ERROR] * <li>Lua string -> Redis bulk reply</li>
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/ScriptOutputType.java:33: error: bad use of '>'
[ERROR] * <li>Lua table (array) -> Redis multi bulk reply (truncated to the first nil inside the Lua array if any)</li>
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/ScriptOutputType.java:34: error: bad use of '>'
[ERROR] * <li>Lua table with a single <code>ok</code> field -> Redis status reply</li>
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/ScriptOutputType.java:35: error: bad use of '>'
[ERROR] * <li>Lua table with a single <code>err</code> field -> Redis error reply</li>
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/ScriptOutputType.java:36: error: bad use of '>'
[ERROR] * <li>Lua boolean false -> Redis Nil bulk reply.</li>
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/protocol/RedisCommand.java:19: error: malformed HTML
[ERROR] * @return CommandOutput<K, V, T>
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/protocol/RedisCommand.java:19: error: bad use of '>'
[ERROR] * @return CommandOutput<K, V, T>
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/protocol/RedisCommand.java:30: error: malformed HTML
[ERROR] * @return CommandArgs<K, V>
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/protocol/RedisCommand.java:30: error: bad use of '>'
[ERROR] * @return CommandArgs<K, V>
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/support/RedisClientFactoryBean.java:14: error: self-closing element not allowed
[ERROR] * </code> <br/>
[ERROR] ^
[ERROR] /Users/mark/git/lettuce/src/main/java/com/lambdaworks/redis/support/package-info.java:2: error: reference not found
[ERROR] * Supportive classes such as {@link com.lambdaworks.redis.support.CdiProducer} for CDI support, {@link com.lambdaworks.redis.support.RedisClientFactoryBean} for Spring.
[ERROR] ^
[ERROR]
[ERROR] Command line was: /Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/bin/javadoc @options @packages
The project consists of 3 maven modules: parent, lettuce and lettuce shaded. All are deployed to mvn central. Searching for lettuce causes to appear all three artifacts.
Expected: Simplify layout to one maven module, add shaded jar as additional artifact with shaded classifier. This removes the separate parent and lettuce-shaded artifacts.
There seems to be a memory leak on reconnection. This seems to be related to a very specific way of the connection going down because I don't always see it and I only see it together with the state exception.
I'm using Netty 4.0.25 with pooled buffers -Dio.netty.allocator.type=pooled
To get the stack I use -Dio.netty.leakDetectionLevel=advanced
Latest lettuce 3.0.2.
2015-01-30 16:21:17,932 WARN io.netty.channel.DefaultChannelPipeline: An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
com.lambdaworks.redis.RedisException: Invalid first byte: 111
at com.lambdaworks.redis.protocol.RedisStateMachine.readReplyType(RedisStateMachine.java:200)
at com.lambdaworks.redis.protocol.RedisStateMachine.decode(RedisStateMachine.java:98)
at com.lambdaworks.redis.protocol.RedisStateMachine.decode(RedisStateMachine.java:61)
at com.lambdaworks.redis.pubsub.PubSubCommandHandler.decode(PubSubCommandHandler.java:55)
at com.lambdaworks.redis.protocol.CommandHandler.channelRead(CommandHandler.java:89)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:308)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:294)
at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:308)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:294)
at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:308)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:294)
at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:308)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:294)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:846)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:130)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:511)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:468)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:382)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:354)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137)
at java.lang.Thread.run(Thread.java:744)
2015-01-30 16:21:17,935 ERROR io.netty.util.ResourceLeakDetector: LEAK: ByteBuf.release() was not called before it's garbage-collected.
Recent access records: 0
Created at:
io.netty.buffer.PooledByteBufAllocator.newHeapBuffer(PooledByteBufAllocator.java:240)
io.netty.buffer.AbstractByteBufAllocator.heapBuffer(AbstractByteBufAllocator.java:136)
io.netty.buffer.AbstractByteBufAllocator.heapBuffer(AbstractByteBufAllocator.java:122)
com.lambdaworks.redis.protocol.CommandHandler.channelRegistered(CommandHandler.java:59)
io.netty.channel.AbstractChannelHandlerContext.invokeChannelRegistered(AbstractChannelHandlerContext.java:133)
io.netty.channel.AbstractChannelHandlerContext.fireChannelRegistered(AbstractChannelHandlerContext.java:119)
io.netty.channel.ChannelInboundHandlerAdapter.channelRegistered(ChannelInboundHandlerAdapter.java:42)
io.netty.channel.AbstractChannelHandlerContext.invokeChannelRegistered(AbstractChannelHandlerContext.java:133)
io.netty.channel.AbstractChannelHandlerContext.fireChannelRegistered(AbstractChannelHandlerContext.java:119)
io.netty.channel.ChannelInboundHandlerAdapter.channelRegistered(ChannelInboundHandlerAdapter.java:42)
io.netty.channel.AbstractChannelHandlerContext.invokeChannelRegistered(AbstractChannelHandlerContext.java:133)
io.netty.channel.AbstractChannelHandlerContext.fireChannelRegistered(AbstractChannelHandlerContext.java:119)
io.netty.channel.ChannelInboundHandlerAdapter.channelRegistered(ChannelInboundHandlerAdapter.java:42)
io.netty.channel.AbstractChannelHandlerContext.invokeChannelRegistered(AbstractChannelHandlerContext.java:133)
io.netty.channel.AbstractChannelHandlerContext.fireChannelRegistered(AbstractChannelHandlerContext.java:119)
io.netty.channel.ChannelInitializer.channelRegistered(ChannelInitializer.java:71)
io.netty.channel.AbstractChannelHandlerContext.invokeChannelRegistered(AbstractChannelHandlerContext.java:133)
io.netty.channel.AbstractChannelHandlerContext.fireChannelRegistered(AbstractChannelHandlerContext.java:119)
io.netty.channel.DefaultChannelPipeline.fireChannelRegistered(DefaultChannelPipeline.java:733)
io.netty.channel.AbstractChannel$AbstractUnsafe.register0(AbstractChannel.java:449)
io.netty.channel.AbstractChannel$AbstractUnsafe.access$100(AbstractChannel.java:377)
io.netty.channel.AbstractChannel$AbstractUnsafe$1.run(AbstractChannel.java:423)
io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:380)
io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:357)
io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116)
io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137)
java.lang.Thread.run(Thread.java:744)
I'll share more information when I find it.
Setup: current master checkout of 3.1-SNAPSHOT: One thread, which has a single RedisClusterConnection<String,String>
The thread does a hgetall in a loop. You want to force a timeout on this thread. Do so by placing a VM breakpoint(pause all threads) in Utf8StringCodec.decode(). Let this hang for a bit(60 seconds I believe is the default timeout)
Now, once you're sure you've expired the timeout, remove the breakpoint and resume the JVM. The command you paused will throw from
FutureSyncInvocationHandler:59 return LettuceFutures.await(command, timeout, unit);
It doesn't seem to occur on a normal RedisConnection.
This is as far as I have made it. What happens next is the original caller gets an exception, which is perfectly fine. However, future calls to hgetall on the same connection will now simply timeout.
! com.lambdaworks.redis.RedisCommandTimeoutException: Command timed out
! at com.lambdaworks.redis.LettuceFutures.await(LettuceFutures.java:68) ~[tanknew1.jar:na]
! at com.lambdaworks.redis.FutureSyncInvocationHandler.handleInvocation(FutureSyncInvocationHandler.java:59) ~[tanknew1.jar:na]
! at com.lambdaworks.com.google.common.reflect.AbstractInvocationHandler.invoke(AbstractInvocationHandler.java:87) ~[tanknew1.jar:na]
! at com.sun.proxy.$Proxy95.hgetall(Unknown Source) ~[na:na]
Additional info: The pause all threads didn't seem to matter. I updated to just pause the single thread in the decode, and it broke the same way.
That was how to reproduce the error. Here is all I've managed to dig up so far.
Did a Thread dump. I have numerous requests blocked waiting for lock on
com.lambdaworks.redis.RedisAsyncConnectionImpl.dispatch()
The guy who has that monitor is blocked on
at com.lambdaworks.redis.protocol.Command.get(Command.java:109)
which is a CountDownLatch.await()
Handle transparent pipelining of following multikey commands:
del
mget
mset
msetnx
ASC signatures have to be created by hand when releasing. Add both assemblies for signing.
When a RedisURI is created without the epoll library on the class path the result is a ClassNotFoundError. This should be changed to:
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.