I get an intermittent missing value from repeated calls to the same (MongoDB) database call which I've converted into an Observable. I've removed all database code to get a minimal test case which only has the Monix bits and I'm still missing values occasionally - usually one or two per 2,000 tests.
According to the docs ConcurrentSubject means "one doesn't need to follow the back-pressure contract", but I get similar failures whether I do or not.
import monix.eval.Task
import monix.reactive.{MulticastStrategy, Observable}
import monix.reactive.subjects.ConcurrentSubject
import org.scalatest.FunSuite
import scala.concurrent.Await
import scala.concurrent.duration.Duration
class Test_JustMonix extends FunSuite {
implicit val scheduler = monix.execution.Scheduler.global
def build(): Observable[Boolean] = {
val subject = ConcurrentSubject(MulticastStrategy.publish[Boolean])
subject.doAfterSubscribe {
Task.eval {
subject.onNext(true)
subject.onComplete()
}
}
}
test("just monix") {
(0 until 20).foreach { loop =>
println(s"loop $loop")
val tOpts = (0 until 100).map { _ => build().firstOptionL }
val tDone = Task.gather(tOpts).map { list =>
val emptyCount = list.count(_.isEmpty)
assert(emptyCount === 0)
}
Await.result(tDone.runToFuture, Duration.Inf)
}
println("Finished")
}
}
On some runs, all 20x100 loops complete correctly - firstOptionL isDefined for all 2,000 results. However, more than 50% of the time the assert(emptyCount === 0) triggers when the value is 1 or sometimes 2, indicating that occasionally I am getting a None value, as if onComplete was occurring before onNext?
This can happen in any of the 20 loops, so it looks like either a race condition or I am misunderstanding the required input. I've tried pretty much all subjects - PublishSubject, with and without BufferedSubscriber and all give similar results.
I've also tried delaying the onComplete until the Ack via
subject.onNext(true).map(_=> subject.onComplete())
and that seems to be fail slightly sooner.
I've also tried MulticastStrategy.replay with no difference.
I'm using Monix 3.0.0-RC3 on Scala 2.12.8.