We now accept a single collection parameter containing keys for diff/inter/union and their …store methods. Note that diff requires a specific key order to denote the initial set to compare to.
Original pull request: #361.
We now shuffle the set of Redis Cluster nodes before retrieving the topology. This change reduces load on the first node in the known nodes set.
Original pull request: #373.
XREAD does no longer apply a COUNT if the count was left unconfigured on StreamReadOperationsBuilder. This removes the limitation of batch size 1 and allows generally an increased throughput in default configuration.
Original Pull Request: #356
Exract nested Stream types into connection.stream package. Extract common code from Template-API based toObjectRecord handling into StreamObjectMapper.
StreamReceiver and StreamMessageListenerContainer now can emit MapRecord or ObjectRecord for easier consumption of stream records.
Original Pull Request: #356
Move API so the stream is more like the hash having dedicated serializers for fields and their values. Also allow appending simple types such as string directly to a stream without having to go through creating a Map. Those simple types can also be read back.
Provide means to hash complex objects when added to the stream.
Update Documentation.
Original Pull Request: #356
We now support Redis Streams to add, read and consume stream records. We introduced StreamOperations, BoundStreamOperations, and ReactiveStreamOperations to interact with Redis Streams using imperative and reactive programming models. Record represents items within a stream. There are various flavors of Stream Records:
* MapRecord (maps to the hash body used in stream messages).
* Binary MapRecord: byte[] and ByteBuffer variants of MapRecord.
* ObjectRecord: Simple and Complex Objects mapped onto the stream body hash using ObjectHashMapper.
Redis Streams are supported for the Lettuce client only as Jedis has not received yet Redis Stream support.
Messages can be created as Map or as object:
redisTemplate.opsForStream().add("my-stream", Collections.singletonMap("key", "value"));
redisTemplate.opsForStream().add(ObjectRecord.create("my-logins", new LoginEvent(…)));
Streams can be consumed by using a StreamMessageListenerContainer that allows for stream subscriptions or a StreamReceiver.
Synchronous Message Listener:
StreamMessageListenerContainer<String, MapRecord<String, String, String>> container = StreamMessageListenerContainer
.create(connectionFactory);
container.start();
Subscription subscription = container.receive(StreamOffset.fromStart("my-stream"), record -> … );
Reactive Message Receiver:
StreamReceiverOptions<String, ObjectRecord<String, LoginEvent>> receiverOptions = StreamReceiverOptions.builder()
.targetType(LoginEvent.class).build();
StreamReceiver<String, ObjectRecord<String, LoginEvent>> receiver = StreamReceiver.create(connectionFactory, receiverOptions);
Flux<ObjectRecord<String, LoginEvent>> messages = receiver.receive(StreamOffset.fromStart("my-logins"));
Original Pull Request: #356
Create unit tests for RedisAtomic counter initialization. Refactor setIfAbsent(…) method to initializeIfAbsent() to not expose additional API methods.
Original pull request: #367.
We now use setIfAbsent to initialize RedisAtomic counters if no initial value was given. Using setIfAbsent turns the initialization into a single atomic step that prevents race conditions of the previously check and set method that required two Redis commands.
Previously, concurrent processes (threads, external changes to Redis) could set the initial value between the existence check and the value set operation that caused the last participant to win.
Original pull request: #367.
LettuceClientConfigurationBuilder now allows configuration of the quiet shutdown period to improve shutdown time of the Netty EventLoop when using non-shared ClientResources.
Original pull request: #363.
This commit adds the following public methods to RedisAtomicInteger,
RedisAtomicLong, and RedisAtomicDouble:
T accumulateAndGet(T updateValue, BinaryOperator<T> accumulatorFunction);
T getAndAccumulate(T updateValue, BinaryOperator<T> accumulatorFunction);
T updateAndGet(UnaryOperator<T> updateFunction);
T getAndUpdate(UnaryOperator<T> updateFunction);
These methods are primarily useful for doing CAS operations with the
help of Binary/UnaryOperators to generate the new value. They mirror
their counterparts on the AtomicInteger and AtomicLong classes
available in the java.util.concurrent.atomic package.
Original pull request: #362.
We now renamed RedisStaticMasterSlaveConfiguration and StaticMasterSlaveConnectionProvider to RedisStaticMasterReplicaConfiguration respective StaticMasterReplicaConnectionProvider to reflect changes in Redis nomenclature regarding replication.
Original Pull Request: #355