Description
While working on RxNetty, a networking library that layers RxJava on top of netty, I have come across a common case of expressing result of an operation as an Observable<Void>
. A typical case being the result of a write
on a Connection
. The API for write looks like:
public Observable<Void> write(Observable<T> msgs);
The return value just represents the asynchronous result of the write and hence does not emit any item, so has the type as Void
.
This works pretty well, however, it becomes awkward when we start doing a bit more complex operations over this write. eg: If I am writing a TCP client that sends a message on the connection and then reads the response from the server, I start doing things like:
connection.write(Observable.just("hello"))
.cast(String.class)
.concatWith(connection.getInput())
(Actual example here)
In this example, connection.getInput()
returns an Observable<T>
emitting items as read on the connection.
and in case, I do not want to wait for write to complete, the code looks like:
connection.write(Observable.just("hello"))
.cast(String.class)
.mergeWith(connection.getInput())
What is awkward in the above example, is the cast(String.class)
. It is completely safe as the write
never emits an item (Void
) so I can merge/concat heterogeneous streams but it is just awkward.
My motivation behind creating this issue is to first see if other folks have come across the same scenario, if so, how have they handled it. Secondly, if this does sound like something worth spending time to make it better, I would like to propose some abstraction on the lines of a VoidObservable
(for the lack of a better name) which basically provides better constructs around:
- Concat with a different type:
write().cast().concatWith()
example above, where it is expected to continue with another stream of a different type (String
in the above example) - Merge with a different type:
write().cast().mergeWith()
example above, where it is expected to eagerly subscribe to the secondObservable
but listen only for errors from theObservable<Void>