Skip to content

Releases: redis/lettuce

5.2.0.RELEASE

26 Sep 14:25
55ebef8
Compare
Choose a tag to compare

The Lettuce team is pleased to announce the Lettuce 5.2.0 release!
This release contains new features, bug fixes, and enhancements.

Most notable changes are:

  • Sentinel refinements
  • Node randomization when reading from Redis Cluster nodes
  • Codec enhancements
  • Migrated tests to JUnit 5

Find the full changelog at the end of this document that lists all 110 tickets.

Work for Lettuce 6, the next major release has already started. Lettuce 6 will support RESP3 and should ship in time for Redis 6.

Thanks to all contributors who made Lettuce 5.2.0.RELEASE possible.

Lettuce requires a minimum of Java 8 to build and run and is compatible with Java 13. It is tested continuously against the latest Redis source-build.

Sentinel refinements

Since this release, Lettuce can connect to Redis Sentinel using secure sockets (SSL) and can authenticate against Sentinel using passwords.
To use SSL, enable SSL usage on RedisURI the same way how it's done for Redis Standalone and Redis Cluster.
Lettuce also introduced a new protocol scheme with rediss-sentinel://. Please note that enabling SSL enables encryption for both, Sentinel and data node communication.

Password authentication follows the same pattern. Setting a password on a Sentinel RedisURI enables password authentication for Sentinel and data nodes.

Read from random Redis Cluster node

Redis Cluster supports now node randomization to avoid excessive usage of individual nodes when reading from these. ReadFrom now exposes a isOrderSensitive() method to indicate whether a ReadFrom setting is order-sensitive or whether respecting order isn't required. Custom ReadFrom implementations should consider this change. ReadFrom.ANY is a newly introduced setting that allows reading from any node (master or a qualified replica) without an ordering preference if multiple replicas qualify for reading.

Codec enhancements

As of this release, we ship two notable enhancements for codecs:

  • CipherCodec for transparent encryption and decryption of values.
  • Codec composition through RedisCodec.of(…) to set up a composed codec from a key and a value codec.

CipherCodec is created by using a delegate codec and CipherSupplier for encryption and decryption. Values are encoded first and then encrypted before values are written to Redis.

SecretKeySpec key = …;
CipherCodec.CipherSupplier encrypt = new CipherCodec.CipherSupplier() {
    @Override
    public Cipher get(CipherCodec.KeyDescriptor keyDescriptor) throws GeneralSecurityException {

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, key);
        return cipher;
    }
};

CipherCodec.CipherSupplier decrypt = (CipherCodec.KeyDescriptor keyDescriptor) -> {

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, key);
    return cipher;
};

RedisCodec<String, String> crypto = CipherCodec.forValues(StringCodec.UTF8, encrypt, decrypt);

CipherCodec supports multiple keys to increment key versions and to decrypt values with older key versions. The code above is to illustrate how to construct CipherCodec and does not guarantee to outline a secure Cipher setup that meets your requirements.

With RedisCodec.of(…), applications can quickly compose a RedisCodec of already existing codecs instead of writing an entire codec from scratch. Codec composition is useful to use different codecs for key and value encoding:

RedisCodec<String, byte[]> composed = RedisCodec.of(StringCodec.ASCII, ByteArrayCodec.INSTANCE);

Read more on Codecs at: https://github.com/lettuce-io/lettuce-core/wiki/Codecs

Commands

Enhancements

  • Make adaptive topology refresh better usable for failover/master-slave promotion changes #672 (Thanks to @mudasirale)
  • Allow randomization of read candidates using Redis Cluster #834 (Thanks to @nborole)
  • AsyncExecutions should implement CompletionStage #862
  • BraveTracing should support custom names for the service name #865 (Thanks to @worldtiki)
  • Emit Connection Error events #885 (Thanks to @squishypenguin)
  • Allow usage of publishOn scheduler for reactive signal emission #905
  • Optimize aggregation buffer cleanup in CommandHandler #906 (Thanks to @gavincook)
  • Add shutdown logging to client, ClientResources, and EventLoopGroupProvider #918
  • Add flag to disable reporting of span tags #920 (Thanks to @worldtiki)
  • Optimization: Use Cluster write connections for read commands when using ReadFrom.MASTER #923
  • ByteBuf.release() was not called before it's garbage-collected #930 (Thanks to @zhouzq)
  • Add cipher codec #934
  • Introduce adaptive trigger event #952
  • Deprecate PING on connect option #965
  • Do not require CLIENT LIST in cluster topology refresh #973 (Thanks to @bentharage)
  • Add support for Redis Sentinel authentication #1002 (Thanks to @ssouris)
  • Improve mutators for ClientOptions, ClusterClientOptions, and ClientResources #1003
  • TopologyComparators performance issue #1011 (Thanks to @alessandrosimi-sa)
  • Attach topology retrieval exceptions when Lettuce cannot retrieve a topology update #1024 (Thanks to @StillerRen)
  • Support TLS connections in Sentinel mode #1048 (Thanks to @ae6rt)
  • Reduce object allocations for assertions #1068
  • Reduce object allocations for Cluster topology parsing #1069
  • Support ByteArrayCodec only for values #1122 (Thanks to @dmandalidis)
  • lettuce#ClusterTopologyRefresh is too slow,because of “client list” #1126 (Thanks to @xjs1919)

Fixes

  • Unable to reconnect Pub/Sub connection with authorization #868 (Thanks to @maestroua)
  • Reduce allocations in topology comparator #870
  • Fix recordCommandLatency to work properly #874 (Thanks to @jongyeol)
  • Bug: Include hostPortString in the error message #876 (Thanks to @LarryBattle)
  • Reference docs CSS prevents HTTPS usage #878
  • ReactiveCommandSegmentCommandFactory resolves StreamingOutput for all reactive types #879 (Thanks to @yozhag)
  • ClassCastException occurs when executing RedisClusterClient::connectPubSub with global timeout feature #895 (Thanks to @be-hase)
  • Flux that reads from a hash, processes elements and writes to a set, completes prematurely #897 (Thanks to @vkurland)
  • Fixed stackoverflow exception inside CommandLatencyCollectorOptions #899 (Thanks to @LarryBattle)
  • PubSubEndpoint.channels and patterns contain duplicate binary channel/pattern names #911 (Thanks to @lwiddershoven)
  • DefaultCommandMethodVerifier reports invalid parameter count #925 (Thanks to @GhaziTriki)
  • Chunked Pub/Sub message receive with interleaved command responses leaves commands uncompleted #936 (Thanks to @GavinTianYang)
  • Fix typo in log message #970 (Thanks to @twz123)
  • Result is lost when published on another executor #986 (Thanks to @trueinsider)
  • Cancel ClusterTopologyRefreshTask in RedisClusterClient.shutdownAsync() #989 (Thanks to @johnsiu)
  • ClassCastException occurs when using RedisCluster with custom-command-interface and Async API #994 (Thanks to @tamanugi)
  • Application-level exceptions in Pub/Sub notifications mess up pub sub decoding state and cause timeouts #997 (Thanks to @giridharkannan)
  • RedisClient.shutdown hangs because event loops terminate before connections are closed #998 (Thanks to @Poorva17)
  • "Knowing Redis" section in documentation has the wrong link for meanings. #1050 (Thanks to @Raghaava)
  • ClassCastException occurs when using RedisCommandFactory with custom commands #1075 (Thanks to @mdebellefeuille)
  • EventLoop thread blocked by EmitterProcessor.onNext(…) causes timeouts #1086 (Thanks to @trishaarao79)
  • RedisClusterNode without slots is never considered having same slots as an equal object #1089 (Thanks to @y2klyf)
  • RedisClusterClient doesn't respect the SocketOptions connectTimeout #1119 (Thanks to @magnusandy)
  • Remove duplicated ConnectionWatchdog #1132 (Thanks to @mors741)

Other

  • Migrate tests to JUnit 5 #430
  • Could not generate CGLIB subclass of class io.lettuce.core.support.ConnectionPoolSupport$1 #843 (Thanks to @peerit12)
  • Adapt to changed terminology for master/replica #845
  • Ability to provide a custom service name for spans #866 (Thanks to @worldtiki)
  • Remove tempusfugit dependency #871
  • Makefile refactor download redis #877 (Thanks to @LarryBattle)
  • Upgrade to Reactor Californium SR1 #883
  • Upgrade to Redis 5 GA #893
  • Document MasterSlave connection behavior on partial node failures #894 (Thanks to @jocull)
  • Upgrade to RxJava 2.2.3 #901
  • Upgrade to Spring Framework 4.3.20.RELEASE #902
  • Upgrade to netty 4.1.30.Final #903
  • Upgrade to Reactor Core 3.2.2.RELEASE #904
  • Deprecate StatefulConnection.reset() #907 (Thanks to @semberal)
  • Upgrade to Reactor Core 3.2.3.RELEASE #931
  • Upgrade to netty 4.1.31.Final #932
  • Upgrade to RxJava 2.2.4 #933
  • Javadoc is missing Javadoc links to Project Reactor types (Flux, Mono) #942
  • Extend year range for 2019 in license headers #950
  • Use ConcurrentHashMap.newKeySet() as replacement of Netty's ConcurrentSet #961
  • Streamline communication sections in readme, issue templates and contribution guide #967
  • Upgrade to stunnel 5.50 #968
  • Replace old reactive API docs #974 (Thanks to @pine)
  • Upgrade to Reactor 3.2.6.RELEASE #975
  • Upgrade to netty 4.1.33.Final #976
  • Upgrade to HdrHistogram 2.1.11 #978
  • Upgrade to RxJava 2.2.6 #979
  • Use JUnit BOM for dependency management and upgrade to JUnit 5.4.0 #980
  • Use logj42 BOM for dependency management and upgrade to 2.11.2 #981
  • Upgrade to AssertJ 3.12.0 #983
  • U...
Read more

5.1.8.RELEASE

30 Jul 12:05
397f211
Compare
Choose a tag to compare

The Lettuce team is pleased to announce the Lettuce 5.1.8 service release!
This release ships bug fixes and dependency upgrades. Upgrading to the new version is recommended.

Thanks to all contributors who made Lettuce 5.1.8.RELEASE possible.

Lettuce requires Java 8 to build and run and #HaveYouSeen, it runs on Java 13.
It is tested continuously against the latest Redis source-build.

Enhancements

  • TopologyComparators performance issue #1011 (Thanks to @alessandrosimi-sa)
  • Attach topology retrieval exceptions when Lettuce cannot retrieve a topology update #1024 (Thanks to @StillerRen)

Fixes

  • ClassCastException occurs when using RedisCommandFactory with custom commands #1075 (Thanks to @mdebellefeuille)
  • EventLoop thread blocked by EmitterProcessor.onNext(…) causes timeouts #1086 (Thanks to @trishaarao79)
  • RedisClusterNode without slots is never considered having same slots as an equal object #1089 (Thanks to @y2klyf)

Other

  • Upgrade to OpenWebBeans 2.0.11 #1062
  • Upgrade to netty 4.1.38.Final #1093
  • Upgrade to Reactor Core 3.2.11.RELEASE #1094
  • Upgrade to Mockito 3.0 #1095
  • Upgrade to JUnit 5.5.1 #1096
  • Update plugin versions #1098

Documentation

Reference documentation: https://lettuce.io/core/5.1.8.RELEASE/reference/
Javadoc: https://lettuce.io/core/5.1.8.RELEASE/api/

5.1.7.RELEASE

09 Jun 14:36
117efa0
Compare
Choose a tag to compare

The Lettuce team is pleased to announce the Lettuce 5.1.7 service release!
This release ships bug fixes and dependency upgrades. Upgrading to the new version is recommended.

Thanks to all contributors who made Lettuce 5.1.7.RELEASE possible.

Lettuce requires Java 8 to build and run and #RunsLikeHeaven on Java 11.
It is tested continuously against the latest Redis source-build.

Enhancements

  • TopologyComparators performance issue #1011 (Thanks to @alessandrosimi-sa)
  • Attach topology retrieval exceptions when Lettuce cannot retrieve a topology update #1024 (Thanks to @StillerRen)

Fixes

  • "Knowing Redis" section in documentation has the wrong link for meanings #1050 (Thanks to @Raghaava)

Other

  • Upgrade to netty 4.1.35.Final #1017
  • Migrate off TopicProcessor to EmitterProcessor #1032
  • Upgrade to Netty 4.1.36.Final #1033
  • Upgrade to JUnit 5.4.2 #1034
  • Upgrade to Mockito 2.27.0 #1035
  • Upgrade to RxJava 2.2.8 #1036
  • Upgrade build plugin dependencies #1037
  • RedisURI: fix missing "the" in Javadoc #1049 (Thanks to @perlun)
  • Upgrade to RxJava 2.2.9 #1054
  • Upgrade to jsr305 3.0.2 #1055
  • Upgrade TravisCI build to Xenial/Java 11 #1056

Documentation

Reference documentation: https://lettuce.io/core/5.1.7.RELEASE/reference/
Javadoc: https://lettuce.io/core/5.1.7.RELEASE/api/

5.1.6.RELEASE

26 Mar 14:38
143da7d
Compare
Choose a tag to compare

The Lettuce team is pleased to announce the Lettuce 5.1.6 service release!
This release ships bug fixes and dependency upgrades. Upgrading to the new version is recommended.

Thanks to all contributors who made Lettuce 5.1.6.RELEASE possible.

Lettuce requires a minimum of Java 8 to build and run and #RunsLikeHeaven on Java 11.
It is tested continuously against the latest Redis source-build.

Enhancements

  • Improve mutators for ClientOptions, ClusterClientOptions, and ClientResources #1003

Fixes

  • ClassCastException occurs when using RedisCluster with custom-command-interface and Async API #994 (Thanks to @tamanugi)
  • Application-level exceptions in Pub/Sub notifications mess up pub sub decoding state and cause timeouts #997 (Thanks to @giridharkannan)
  • RedisClient.shutdown hangs because event loops terminate before connections are closed #998 (Thanks to @Poorva17)

Other

  • Upgrade to Reactor Core 3.2.8.RELEASE #1006

Documentation

Reference documentation: https://lettuce.io/core/5.1.6.RELEASE/reference/
Javadoc: https://lettuce.io/core/5.1.6.RELEASE/api/

5.1.5.RELEASE

06 Mar 12:38
de61c62
Compare
Choose a tag to compare

The Lettuce team is pleased to announce the Lettuce 5.1.5 service release!
This release ships with two critical fixes, primarily for the recently introduced reactive signal emission on non-I/O threads, so reactive single-connection systems can utilize more threads for item processing and are not limited to a single thread. The issue that is being fixed is retention of signal ordering as signals can be dispatched out of order.

Thanks to all contributors who made Lettuce 5.1.5.RELEASE possible.

Lettuce requires a minimum of Java 8 to build and run and #RunsLikeHeaven on Java 11.
It is tested continuously against the latest Redis source-build.

Fixes

  • Result is lost when published on another executor #986 (Thanks to @trueinsider)
  • Cancel ClusterTopologyRefreshTask in RedisClusterClient.shutdownAsync() #989 (Thanks to @johnsiu)

Other

  • Upgrade to AssertJ 3.12.0 #983
  • Upgrade to AssertJ 3.12.1 #991
  • Javadoc is missing Javadoc links to Project Reactor types #942

Documentation

Reference documentation: https://lettuce.io/core/5.1.5.RELEASE/reference/
Javadoc: https://lettuce.io/core/5.1.5.RELEASE/api/

5.1.4.RELEASE

12 Feb 11:33
b1c4ee0
Compare
Choose a tag to compare

The Lettuce team is pleased to announce the Lettuce 5.1.4 service release!
This release ships with 14 tickets fixed. This release introduces reactive signal emission on non-I/O threads, so reactive single-connection systems can utilize more threads for item processing and are not limited to a single thread.

Thanks to all contributors who made Lettuce 5.1.4.RELEASE possible.

Lettuce requires a minimum of Java 8 to build and run and #RunsLikeHeaven on Java 11.
It is tested continuously against the latest Redis source-build.

Enhancements

  • Allow usage of publishOn scheduler for reactive signal emission #905

Fixes

  • Chunked Pub/Sub message receive with interleaved command responses leaves commands uncompleted #936 (Thanks to @GavinTianYang)
  • Fix typo in log message #970 (Thanks to @twz123)

Other

  • Javadoc is missing Javadoc links to Project Reactor types (Flux, Mono) #942
  • Extend year range for 2019 in license headers #950
  • Streamline communication sections in readme, issue templates and contribution guide #967
  • Upgrade to stunnel 5.50 #968
  • Replace old reactive API docs #974 (Thanks to @pine)
  • Upgrade to Reactor 3.2.6.RELEASE #975
  • Upgrade to netty 4.1.33.Final #976
  • Upgrade to HdrHistogram 2.1.11 #978
  • Upgrade to RxJava 2.2.6 #979
  • Use JUnit BOM for dependency management and upgrade to JUnit 5.4.0 #980
  • Use logj42 BOM for dependency management and upgrade to 2.11.2 #981

Documentation

Reference documentation: https://lettuce.io/core/5.1.4.RELEASE/reference/
Javadoc: https://lettuce.io/core/5.1.4.RELEASE/api/

5.1.3.RELEASE

26 Nov 14:54
d1ec935
Compare
Choose a tag to compare

The Lettuce team is pleased to announce the Lettuce 5.1.3 service release!
This release ships with 9 tickets fixed. Upgrading is strongly recommended for users of Pub/Sub with the byte-array codec.

Thanks to all contributors who made Lettuce 5.1.3.RELEASE possible.

Lettuce requires a minimum of Java 8 to build and run and #RunsLikeHeaven on Java 11.
It is tested continuously against the latest Redis source-build.

Enhancements

  • Add shutdown logging to client, ClientResources, and EventLoopGroupProvider #918
  • Optimization: Use Cluster write connections for read commands when using ReadFrom.MASTER #923
  • ByteBuf.release() was not called before it's garbage-collected #930 (Thanks to @zhouzq)

Fixes

  • PubSubEndpoint.channels and patterns contain duplicate binary channel/pattern names #911 (Thanks to @lwiddershoven)
  • DefaultCommandMethodVerifier reports invalid parameter count #925 (Thanks to @GhaziTriki)

Other

  • Document MasterSlave connection behavior on partial node failures #894 (Thanks to @jocull)
  • Upgrade to Reactor Core 3.2.3.RELEASE #931
  • Upgrade to netty 4.1.31.Final #932
  • Upgrade to RxJava 2.2.4 #933

Documentation

Reference documentation: https://lettuce.io/core/5.1.3.RELEASE/reference/
Javadoc: https://lettuce.io/core/5.1.3.RELEASE/api/

5.1.2.RELEASE

26 Oct 12:49
6567767
Compare
Choose a tag to compare

The Lettuce team is pleased to announce the Lettuce 5.1.2 service release!
This release ships with 9 tickets fixed. Upgrading is strongly recommended for users of the reactive API.

Thanks to all contributors who made Lettuce 5.1.2.RELEASE possible.

Lettuce requires a minimum of Java 8 to build and run and #RunsLikeHeaven on Java 11.
It is tested continuously against the latest Redis source-build.

Fixes

  • Revert generics signature change in ConnectionPoolSupport #886
  • ClassCastException occurs when executing RedisClusterClient::connectPubSub with global timeout feature #895 (Thanks to @be-hase)
  • Flux that reads from a hash, processes elements and writes to a set, completes prematurely #897 (Thanks to @vkurland)
  • Fixed stackoverflow exception inside CommandLatencyCollectorOptions #899 (Thanks to @LarryBattle)

Other

  • Upgrade to Redis 5 GA #893
  • Upgrade to RxJava 2.2.3 #901
  • Upgrade to Spring Framework 4.3.20.RELEASE #902
  • Upgrade to netty 4.1.30.Final #903
  • Upgrade to Reactor Core 3.2.2.RELEASE #904

Documentation

Reference documentation: https://lettuce.io/core/5.1.2.RELEASE/reference/
Javadoc: https://lettuce.io/core/5.1.2.RELEASE/api/

5.1.1.RELEASE

12 Oct 18:22
8ed4bca
Compare
Choose a tag to compare

The Lettuce team is pleased to announce the Lettuce 5.1.1 service release!
This release fixes 9 bugs in total.

Thanks to all contributors who made Lettuce 5.1.1.RELEASE possible.

Lettuce requires a minimum of Java 8 to build and run and is compatible with Java 11. It is tested continuously against the latest Redis source-build.

Fixes

  • Unable to reconnect Pub/Sub connection with authorization #868 (Thanks to @maestroua)
  • Reduce allocations in topology comparator #870
  • Fix recordCommandLatency to work properly #874 (Thanks to @jongyeol)
  • Bug: Include hostPortString in the error message #876 (Thanks to @LarryBattle)
  • Reference docs CSS prevents HTTPS usage #878
  • ReactiveCommandSegmentCommandFactory resolves StreamingOutput for all reactive types #879 (Thanks to @yozhag)

Other

  • Migrate tests to JUnit 5 #430
  • Remove tempusfugit dependency #871
  • Makefile refactor download redis #877 (Thanks to @LarryBattle)
  • Upgrade to Reactor Californium SR1 #883

Documentation

5.1.0.RELEASE

19 Sep 19:59
5a9c5ec
Compare
Choose a tag to compare

The Lettuce team is pleased to announce the Lettuce 5.1.0 release!
This release contains new features, bugfixes, and enhancements.

Most notable changes are:

  • Support for Redis Streams
  • Asynchronous pool implementation
  • SCAN streams, and initial
  • Global command timeouts (disabled by default)
  • Asynchronous connect methods for Master/Replica and Sentinel
  • Brave (OpenZipkin) tracing support
  • Lettuce build is now Java 11 compatible

We started efforts to adapt improvements in Redis terminology about Master/Replica with this release. This release ships documentation changes referring to the existing API as Master/Replica where possible.

We will introduce with the upcoming releases support for the new API methods (REPLICAOF) without breaking the public API. Expect breaking changes in a much later release which gives plenty of time to upgrade.

Find the full change log at the end of this document that lists all 108 tickets.

Thanks to all contributors who made Lettuce 5.1.0.RELEASE possible.

Lettuce requires a minimum of Java 8 to build and run and is compatible with Java 11. It is tested continuously against the latest Redis source-build.

New Exceptions for Redis Responses

This release introduces new Exception types for the following Redis responses:

  • LOADING: RedisLoadingException
  • NOSCRIPT: RedisNoScriptException
  • BUSY: RedisBusyException

All exception types derive from RedisCommandExecutionException and do not require changes in application code.

Redis Streams

Redis 5.0 is going to ship with support for a Stream data structure. A stream is a log of events that can be consumed sequentially. A Stream message consists of an id and a body represented as hash (or Map<K, V>).

Lettuce provides access to Stream commands through RedisStreamCommands supporting synchronous, asynchronous, and reactive execution models. All Stream commands are prefixed with X (XADD, XREAD, XRANGE).

Stream messages are required to be polled. Polling can return either in a non-blocking way without a message if no message is available, or, in a blocking way.
XREAD allows to specify a blocking duration in which the connection is blocked until either the timeout is exceeded or a Stream message arrives.

The following example shows how to append and read messages from a Redis Stream:

// Append a message to the stream
String messageId = redis.xadd("my-stream", Collections.singletonMap("key", "value"));

// Read a message
List<StreamMessage<String, String>> messages = redis.xread(StreamOffset.from("my-stream", messageId));


redis.xadd("my-stream", Collections.singletonMap("key", "value"));

// Blocking read
List<StreamMessage<String, String>> messages = redis.xread(XReadArgs.Builder.block(Duration.ofSeconds(2)), 
                                                           StreamOffset.latest("my-stream"));

Redis Streams support the notion of consumer groups. A consumer group is a group of one or more consumers that tracks the last consumed Stream message and allows explicit acknowledgment of consumed messages.

// Setup stream, see https://github.com/antirez/redis/issues/4824
redis.xadd("my-stream", Collections.singletonMap("key", "value"));

// Create consumer group
redis.xgroupCreate("my-stream", "my-group", "$");
redis.xadd("my-stream", Collections.singletonMap("key", "value"));

// Read stream messages in the context of a consumer
List<StreamMessage<String, String>> messages = redis.xreadgroup(Consumer.from("my-stream", "consumer1"),
                XReadArgs.Builder.noack(),
                StreamOffset.lastConsumed(key));

// process message// Acknowledge message
redis.xack(key, "group", messages.get(0).getId());

Scan Stream

Lettuce 5.1 ships with a reactive SCAN stream API that allows reactive and demand-aware usage of Redis' SCAN commands. SCAN is an interator-based command that requires multiple round-trips to Redis to scan the keyspace or a particular data structure. Instead of calling SCAN from your application code, you can use ScanStream as entrypoint to SCAN, HSCAN, SSCAN, and ZSCAN operations. ScanStream returns a Flux that can be consumed as a single stream without the need of continuing the actual iteration. That's covered by Lettuce for you.

The LIMIT argument controls the batchsize. Demand (backpressure) is translated into cursor call. If you stop consuming the stream, no further SCAN calls are issued.

RedisReactiveCommands<String, String> reactive = redis.getStatefulConnection().reactive();

Flux<String> keys = ScanStream.scan(reactive, ScanArgs.Builder.limit(200));

Asynchronous non-blocking Connection Pooling

Right now, applications that utilize connection pooling in combination with a non-blocking API (asynchronous or reactive API users) are limited to Apache Commons Pool which is a blocking object pool implementation.

This release ships with non-blocking pooling support through AsyncPool that is obtained from AsyncConnectionPoolSupport. The pooling API allows for various
implementations. As of Lettuce 5.1, a bounded pool is provided that allows limiting and that signals pool exhaustion by emitting NoSuchElementException.

The pooling API returns CompletableFuture instances to synchronize acquire and release operations. AsyncPool does not require external dependencies and features an improved performance profile in comparison to Apache Commons Pool 2. This non-blocking pooling API is not a replacement for the blocking pool although it's possible that may provide a blocking layer that exports the pooling functionality through org.apache.commons.pool2.ObjectPool.

The following example show how to use AsyncPool.

AsyncPool<StatefulRedisConnection<String, String>> pool = AsyncConnectionPoolSupport.createBoundedObjectPool(
        () -> client.connectAsync(StringCodec.UTF8, uri),
        BoundedPoolConfig.builder()
                    .minIdle(4)
                    .maxIdle(8)
                    .maxTotal(16)
                    .testOnAcquire()
                    .build());

// Acquire connection and do some work
CompletableFuture<StatefulRedisConnection<String, String>> acquire = pool.acquire();

acquire.thenAccept(connection -> {

    connection.async().set("key", "value").whenComplete((v, e) -> {
        pool.release(connection);
    });
});


// later
CompletableFuture<Void> closeFuture = pool.closeAsync();

Global Command Timeouts

Lettuce can be used through various APIs. The most common one is the synchronous API which emulates blocking behavior on top of a reactive and non-blocking driver. A natural aspect of blocking APIs are timeouts when it comes to I/O. Using the asynchronous or reactive API do not have timeouts as there was no active component that tracked command runtime durations.

With Lettuce 5.1, you get the possibility to configure a global command timeout through ClientOptions and TimeoutOptions that can determine timeouts on a RedisCommand basis. This timeout applies on a command basis and completes commands with RedisCommandTimeoutException.

You can change the timeout on running connections through RedisURI.setTimeout(…), RedisClient.setDefaultTimeout(…), and StatefulConnection.setTimeout(…) if TimeoutOptions are enabled - global command timeouts are disabled by default.

TimeoutOptions timeoutOptions = TimeoutOptions.enabled(Duration.ofMinutes(1));

ClientOptions.builder().timeoutOptions(timeoutOptions).build();

Add tracing support using Brave (OpenZipkin)

Lettuce now supports command tracing using Brave. Tracing can be configured through ClientResources. The parent span is propagated either through Tracing.currentTracer() (synchronous/asynchronous usage) or by registering a Brave Span in the Reactor context when using Reactive execution.

Lettuce wraps Brave data models to support tracing in a vendor-agnostic way if Brave is on the class path.

Usage example:

Tracing tracing = …;

ClientResources clientResources = ClientResources.builder().tracing(BraveTracing.create(tracing)).build();

RedisClient client = RedisClient.create(clientResources, redisUri);

StatefulRedisConnection<String, String> connection = client.connect();

connection.sync().get(…) // Tracing tries to obtain the current tracer from Tracing.currentTracer()

connection.reactive().get(…) // Tracing tries to obtain the current tracer from Reactor's Context

A note on reactive Tracing: Reactive Tracing with Brave requires either a Span or a TraceContext object to be available in Reactor's Context.

Commands

  • Add AUTH option to MIGRATE command #733
  • Add MASTER type to KillArgs #760
  • Add support for ZPOPMIN, ZPOPMAX, BZPOPMIN, BZPOPMAX commands #778
  • Add REPLACE option to RESTORE. #783 (Thanks to @christophstrobl)
  • Add XGROUP DESTROY #789
  • Add support for CLIENT UNBLOCK #812
  • Support for approximate trimming in XAddArgs #846

Enhancements

  • Support for command timeouts (async, reactive) #435
  • Use object pooling for collections inside a single method and Command/CommandArgs with a small scope #459
  • Cancel commands after disconnect in at-most-once mode. #547
  • Add support for Redis streams #606
  • Introduce dedicated exceptions for NOSCRIPT and BUSY responses #620 (Thanks to @DaichiUeura)
  • Non-blocking connection pooling #631
  • Introduce fast-path publishing in RedisPublisher #637
  • Add reactive scanning #638
  • Asynchronous connection initialization #640
  • Create reusable abstraction for non-blocking and keyed connection pro...
Read more