Add support for XCLAIM in StreamOperations

Closes #2465
This commit is contained in:
Marcin Zielinski
2022-11-26 21:54:16 +01:00
committed by John Blum
parent a39b8b6953
commit 992905360b
6 changed files with 165 additions and 11 deletions

View File

@@ -20,6 +20,7 @@ import reactor.core.publisher.Mono;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
@@ -32,6 +33,7 @@ import org.springframework.core.convert.ConversionService;
import org.springframework.data.domain.Range;
import org.springframework.data.redis.connection.Limit;
import org.springframework.data.redis.connection.ReactiveStreamCommands;
import org.springframework.data.redis.connection.RedisStreamCommands.XClaimOptions;
import org.springframework.data.redis.connection.convert.Converters;
import org.springframework.data.redis.connection.stream.ByteBufferRecord;
import org.springframework.data.redis.connection.stream.Consumer;
@@ -141,6 +143,21 @@ class DefaultReactiveStreamOperations<K, HK, HV> implements ReactiveStreamOperat
return createMono(connection -> connection.xAdd(serializeRecord(input)));
}
@Override
public Flux<MapRecord<K, HK, HV>> claim(K key, String group, String newOwner, Duration minIdleTime,
RecordId... recordIds) {
return createFlux(connection -> connection.xClaim(rawKey(key), group, newOwner, minIdleTime, recordIds)
.map(this::deserializeRecord));
}
@Override
public Flux<MapRecord<K, HK, HV>> claim(K key, String group, String newOwner, XClaimOptions xClaimOptions) {
return createFlux(
connection -> connection.xClaim(rawKey(key), group, newOwner, xClaimOptions).map(this::deserializeRecord));
}
@Override
public Mono<Long> delete(K key, RecordId... recordIds) {

View File

@@ -16,6 +16,7 @@
package org.springframework.data.redis.core;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -26,6 +27,7 @@ import org.springframework.core.convert.ConversionService;
import org.springframework.data.domain.Range;
import org.springframework.data.redis.connection.Limit;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisStreamCommands.XClaimOptions;
import org.springframework.data.redis.connection.stream.ByteRecord;
import org.springframework.data.redis.connection.stream.Consumer;
import org.springframework.data.redis.connection.stream.MapRecord;
@@ -132,6 +134,35 @@ class DefaultStreamOperations<K, HK, HV> extends AbstractOperations<K, Object> i
return execute(connection -> connection.xAdd(binaryRecord));
}
@Override
public List<MapRecord<K, HK, HV>> claim(K key, String group, String newOwner, Duration minIdleTime,
RecordId... recordIds) {
byte[] rawKey = rawKey(key);
return execute(new RecordDeserializingRedisCallback() {
@Nullable
@Override
List<ByteRecord> inRedis(RedisConnection connection) {
return connection.streamCommands().xClaim(rawKey, group, newOwner, minIdleTime, recordIds);
}
});
}
@Override
public List<MapRecord<K, HK, HV>> claim(K key, String group, String newOwner, XClaimOptions xClaimOptions) {
byte[] rawKey = rawKey(key);
return execute(new RecordDeserializingRedisCallback() {
@Nullable
@Override
List<ByteRecord> inRedis(RedisConnection connection) {
return connection.streamCommands().xClaim(rawKey, group, newOwner, xClaimOptions);
}
});
}
@Override
public Long delete(K key, RecordId... recordIds) {

View File

@@ -18,6 +18,7 @@ package org.springframework.data.redis.core;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.time.Duration;
import java.util.Arrays;
import java.util.Map;
@@ -25,6 +26,7 @@ import org.reactivestreams.Publisher;
import org.springframework.data.domain.Range;
import org.springframework.data.redis.connection.Limit;
import org.springframework.data.redis.connection.RedisStreamCommands.XClaimOptions;
import org.springframework.data.redis.connection.stream.*;
import org.springframework.data.redis.connection.stream.Record;
import org.springframework.data.redis.connection.stream.StreamInfo.XInfoConsumer;
@@ -126,6 +128,35 @@ public interface ReactiveStreamOperations<K, HK, HV> extends HashMapperProvider<
*/
Mono<RecordId> add(Record<K, ?> record);
/**
* Changes the ownership of a pending message, so that the new owner is the consumer specified as the command argument.
* The message is claimed only if its idle time is greater the minimum idle time specified when calling XCLAIM
*
* @param key the stream key.
* @param group name of the consumer group.
* @param newOwner name of the consumer claiming the message.
* @param minIdleTime idle time required for a message to be claimed.
* @param recordIds record IDs to be claimed
*
* @return the {@link Flux} of claimed MapRecords.
* @see <a href="https://redis.io/commands/xclaim/">Redis Documentation: XCLAIM</a>
*/
Flux<MapRecord<K, HK, HV>> claim(K key, String group, String newOwner, Duration minIdleTime, RecordId... recordIds);
/**
* Changes the ownership of a pending message, so that the new owner is the consumer specified as the command argument.
* The message is claimed only if its idle time is greater the minimum idle time specified when calling XCLAIM
*
* @param key the stream key.
* @param group name of the consumer group.
* @param newOwner name of the consumer claiming the message.
* @param xClaimOptions additional parameters for the CLAIM call.
*
* @return the {@link Flux} of claimed MapRecords.
* @see <a href="https://redis.io/commands/xclaim/">Redis Documentation: XCLAIM</a>
*/
Flux<MapRecord<K, HK, HV>> claim(K key, String group, String newOwner, XClaimOptions xClaimOptions);
/**
* Removes the specified records from the stream. Returns the number of records deleted, that may be different from
* the number of IDs passed in case certain IDs do not exist.

View File

@@ -17,12 +17,14 @@ package org.springframework.data.redis.core;
import reactor.core.publisher.Mono;
import java.time.Duration;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.springframework.data.domain.Range;
import org.springframework.data.redis.connection.Limit;
import org.springframework.data.redis.connection.RedisStreamCommands.XClaimOptions;
import org.springframework.data.redis.connection.stream.*;
import org.springframework.data.redis.connection.stream.Record;
import org.springframework.data.redis.connection.stream.StreamInfo.XInfoConsumers;
@@ -119,6 +121,35 @@ public interface StreamOperations<K, HK, HV> extends HashMapperProvider<HK, HV>
@Nullable
RecordId add(Record<K, ?> record);
/**
* Changes the ownership of a pending message, so that the new owner is the consumer specified as the command argument.
* The message is claimed only if its idle time is greater the minimum idle time specified when calling XCLAIM
*
* @param key the stream key.
* @param group name of the consumer group.
* @param newOwner name of the consumer claiming the message.
* @param minIdleTime idle time required for a message to be claimed.
* @param recordIds record IDs to be claimed
*
* @return list of claimed MapRecords.
* @see <a href="https://redis.io/commands/xclaim/">Redis Documentation: XCLAIM</a>
*/
List<MapRecord<K, HK, HV>> claim(K key, String group, String newOwner, Duration minIdleTime, RecordId... recordIds);
/**
* Changes the ownership of a pending message, so that the new owner is the consumer specified as the command argument.
* The message is claimed only if its idle time is greater the minimum idle time specified when calling XCLAIM
*
* @param key the stream key.
* @param group name of the consumer group.
* @param newOwner name of the consumer claiming the message.
* @param xClaimOptions additional parameters for the CLAIM call.
*
* @return list of claimed MapRecords.
* @see <a href="https://redis.io/commands/xclaim/">Redis Documentation: XCLAIM</a>
*/
List<MapRecord<K, HK, HV>> claim(K key, String group, String newOwner, XClaimOptions xClaimOptions);
/**
* Removes the specified records from the stream. Returns the number of records deleted, that may be different from
* the number of IDs passed in case certain IDs do not exist.