1

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.

ElaineC
  • 11
  • 1

0 Answers0