ReactiveX / RxGo

Reactive Extensions for the Go language.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Deadlock when throwing error from FlatMap in connectable observable

kyle-hiller-nh opened this issue · comments

I am trying to use a connectable observable to allow multiple observers to watch some data and transform it. If an error occurs in the observable, I would like to use the StopOnError functionality to stop the whole pipeline. However, whenever I throw an error from the FlatMap operation in this observable, the program deadlocks in goparkwith waitReason: waitReasonChanReceive. It seems like a channel is waiting to receive the error but there is nothing ever sent to it? I do not understand the implementation of Connectable observables well enough to know why this might be the case.

I have tried multiple ways of creating the Error like rxgo.Thrown(err), rxgo.FromChannel(rxgo.JustItem(rxgo.Error(err)).Observe()), manually creating a channel and putting the error item onto it, etc.

Is this a bug? Is there some way to work around this?

To Reproduce

  1. Create an Observable using FromChannel()
  2. Create a Connectable observable by calling FlatMap on an observable and passing the rxgo.WithPublishStrategy() option.
  3. Make the FlatMap operation throw an error
  4. Create an observer of this observable
  5. call Connect()on the observable
  6. Try get an item from the Observer (e.g. First())
  7. Deadlock

Expected behavior
The program should not deadlock and the Observer should resolve to the error.

Would #279 fix this? I know this behavior works correctly using Map and that PR seems to make their behavior much more similar.

On closer inspection, this actually only occurs when the FlatMap observable is called on an observable that was created using rxgo.FromChannel(), like if you used Reduce().Observe(). It can be worked around by using Reduce.Get() and then rxgo.Just() after handling the output of Get().