DEV Community

Cover image for Matt's Tidbits #41 - Converting a BehaviorRelay into a PublishRelay
Matthew Groves
Matthew Groves

Posted on • Originally published at Medium

Matt's Tidbits #41 - Converting a BehaviorRelay into a PublishRelay

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)