Last week I explained the way errors don’t propagate outside of a doOnSubscribe()
block. This time, I wanted to share an exciting discovery — how to convert a BehaviorRelay
to a PublishRelay
(and why you would want to).
On the project I’ve been working on recently, I was presented with an interesting challenge — I have a BehaviorRelay
and need it to behave like a PublishRelay
.
What’s the difference you ask? They’re both a type of RxJava Observable
that does not allow for errors to be emitted. However, there is one fundamental difference — a BehaviorRelay
will emit the most recent item when someone subscribes to it, while a PublishRelay
will not.
Given that RxJava has nearly as many operators as emacs, you’d think there would be a built-in easy way to convert from a BehaviorRelay
to a PublishRelay
. Unfortunately, this is not the case. But, we can do a pretty good job of building one on our own!
Here’s what I came up with:
The most obviously important part is the hasValue()
check and corresponding skip(1)
statement. This allows us to check if the BehaviorRelay
has a value that it would emit upon subscription.
However, that’s not all of it — the Observable.defer()
is also very important — this guarantees that we’re not checking if the BehaviorRelay
has a value until the client subscribes to the Observable
we’re returning. This means we reduce the window of time during which our call to hasValue()
might change.
Unfortunately, this does not completely eliminate the possibility of things getting messed up — it’s possible, especially in a multi-threaded environment, that when we call behaviorRelay.hasValue()
it returns false
, but by the time we get ready to return the behaviorRelay
itself a value will have been emitted, which we may have been intending to skip.
I’m not crazy about there still being a chance for things to go wrong, but this is the best I could come up with. Do you have an idea for how to improve this further? If so, please let me know in the comments! And, please follow me on Medium if you’re interested in being notified of future tidbits.
Interested in joining the awesome team here at Intrepid? We’re hiring!
This tidbit was discovered on October 24, 2019.
Top comments (0)