Skip to content

Observable<Void> Usage or VoidObservable #3037

Closed
@NiteshKant

Description

@NiteshKant

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 second Observable but listen only for errors from the Observable<Void>

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions