The future of the lettuce reactive API
See original GitHub issuelettuce brought with 4.0 a reactive API based on rx-java 1. The reactive API mirrors mostly the asynchronous API and resolves List
and Set
types into Observable
. The reactive API has some drawbacks:
- It emits
null
values - Method invocation and result processing are decoupled. In some cases, data ordering depends on the input arguments that can make it hard to correlate input parameters to result
- (more to come)?
Reactive libraries move towards Reactive Streams, and the rx-java 1 library will be superseded by rx-java 2 that will use Reactive Streams as well.
Especially the null
handling is in Reactive Streams pretty clear defined: null
values are not allowed which means lettuce has to react to this requirement.
The null
problem
Redis emits null
in several cases. The most frequent case might be MGET
to retrieve values by a key. In case the key does not exist, a null
value is returned. Returning null
values is discouraged anyways, with Reactive Streams it’s no longer allowed. This rule requires lettuce to introduce a representation for absent values. While it’s simple for singular values like GET
to use a Mono
(see Project Reactor, multiple absent values are harmful to the API consumer because it cannot be longer correlated, which value of e.g. a MGET
is absent.
It’s obvious for at least commands returning multiple values by key to return a different result type than the value type. Something like Publisher<Value<T>>
could wrap the value.
The ordering problem
Result order in the sync/async API is not an issue. The result type of commands using a particular order is either List
or a Map
using a LinkedHashMap
implementation. The input argument order can be easily matched against the result ordering since both values are quite near to each other. Reactive APIs introduce the possibility for deferred and lazy event processing where the stream can be processed in a different place than the command invocation. Emitting just the value type might be not enough in that case.
A possible solution might introduce a keyed value type that holds the correlation to the input argument. Currently GET
and MGET
and its variants are known to fall into this category of commands.
Something like Publisher<KeyValue<K, V>>
could wrap the value.
Issue Analytics
- State:
- Created 8 years ago
- Comments:12 (8 by maintainers)
Top GitHub Comments
Users of RxJava 1 can benefit from the upcoming command interfaces abstraction (dynamic API) by declaring RxJava1/RxJava2 return types. Wrapper type conversion happens under the hood and the migration path improves by retaining RxJava on a different abstraction level, see #383.
RxJava announced its roadmap towards 2.0. RxJava will feature a couple of breaking changes. It will be compliant with Reactive Streams but requires each
Observable
andSingle
to be converted to aFlowable
. The other way round,Observable
/Single
creation is possible withObservable.from(Publisher)
.I’ve worked with Reactive Streams and RxJava and I have to admit the Project Reactor implementation provides a very clean an concise API. I’m tempted to drop RxJava in favor of Project Reactor. Supporting both libraries is not doable by myself. RxJava users can convert
Publisher <-> Observable
in both directions using the provided Project Reactor adapters.Any opinions?