DATAREDIS-645 - Introduce absent values in ReactiveStringCommands.
We now return AbsentByteBufferResponse to indicate absence of a Redis key when retrieving the key as top-level element. CommandResponse indicates via isPresent its presence or absence of a response value. Omission of absent values can cause a stream with a different response structure compared to the request. Retaining the stream sequence is required for response to request correlation. GET and GETSET commands use presence of CommandResponse to filter response emission. Both commands return a single element so absence does not interferes with the request structure. Previously, we just returned an empty byte-array that caused downstream errors deserializing and emitting null values that are prohibited in Reactive Streams. Original Pull Request: #249
This commit is contained in:
committed by
Christoph Strobl
parent
18a6440e98
commit
d6ea867e37
@@ -245,6 +245,14 @@ public interface ReactiveRedisConnection extends Closeable {
|
||||
|
||||
private final I input;
|
||||
private final O output;
|
||||
|
||||
/**
|
||||
* @return {@literal true} if the response is present. An absent {@link CommandResponse} maps to Redis
|
||||
* {@literal (nil)}.
|
||||
*/
|
||||
public boolean isPresent() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -267,6 +275,26 @@ public interface ReactiveRedisConnection extends Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link CommandResponse} implementation for {@link ByteBuffer} responses for absent keys.
|
||||
*/
|
||||
class AbsentByteBufferResponse<I> extends ByteBufferResponse<I> {
|
||||
|
||||
private final static ByteBuffer EMPTY_BYTE_BUFFER = ByteBuffer.wrap(new byte[0]);
|
||||
|
||||
public AbsentByteBufferResponse(I input) {
|
||||
super(input, EMPTY_BYTE_BUFFER);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.ReactiveRedisConnection.CommandResponse#isPresent()
|
||||
*/
|
||||
@Override
|
||||
public boolean isPresent() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link CommandResponse} implementation for {@link List} responses.
|
||||
*/
|
||||
|
||||
@@ -199,7 +199,8 @@ public interface ReactiveStringCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
return get(Mono.just(new KeyCommand(key))).next().map(CommandResponse::getOutput);
|
||||
return get(Mono.just(new KeyCommand(key))).next().filter(CommandResponse::isPresent)
|
||||
.map(CommandResponse::getOutput);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -225,7 +226,8 @@ public interface ReactiveStringCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
|
||||
return getSet(Mono.just(SetCommand.set(key).value(value))).next().map(ByteBufferResponse::getOutput);
|
||||
return getSet(Mono.just(SetCommand.set(key).value(value))).next().filter(CommandResponse::isPresent)
|
||||
.map(ByteBufferResponse::getOutput);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.List;
|
||||
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.springframework.data.domain.Range;
|
||||
import org.springframework.data.redis.connection.ReactiveRedisConnection.AbsentByteBufferResponse;
|
||||
import org.springframework.data.redis.connection.ReactiveRedisConnection.BooleanResponse;
|
||||
import org.springframework.data.redis.connection.ReactiveRedisConnection.ByteBufferResponse;
|
||||
import org.springframework.data.redis.connection.ReactiveRedisConnection.KeyCommand;
|
||||
@@ -113,7 +114,7 @@ class LettuceReactiveStringCommands implements ReactiveStringCommands {
|
||||
}
|
||||
|
||||
return cmd.getset(command.getKey(), command.getValue()).map((value) -> new ByteBufferResponse<>(command, value))
|
||||
.defaultIfEmpty(new ByteBufferResponse<>(command, EMPTY_BYTE_BUFFER));
|
||||
.defaultIfEmpty(new AbsentByteBufferResponse<>(command));
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -129,7 +130,7 @@ class LettuceReactiveStringCommands implements ReactiveStringCommands {
|
||||
Assert.notNull(command.getKey(), "Key must not be null!");
|
||||
|
||||
return cmd.get(command.getKey()).map((value) -> new ByteBufferResponse<>(command, value))
|
||||
.defaultIfEmpty(new ByteBufferResponse<>(command, EMPTY_BYTE_BUFFER));
|
||||
.defaultIfEmpty(new AbsentByteBufferResponse<>(command));
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user