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
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.