Uploaded image for project: 'Java Driver'
  1. Java Driver
  2. JAVA-4303

Improve map/flatmap of Publisher[Void]

    • Major Change
    • Needed
    • Hide

      There are multiple changes that break compile-time compatibility (the source code will likely have to be changed to work the the upgraded driver version). Let's mention them in What's new:

      • `org.reactivestreams.Publisher[Void]` is no longer automatically convertible to `org.mongodb.scala.SingleObservable[Void]`, because we removed the `org.mongodb.scala.ObservableImplicits.ToSingleObservableVoid` implicit class.
      • Our API no longer exposes `org.mongodb.scala.Observable[Void]`. Instead, it exposes `org.mongodb.scala.Observable[Unit]`. The documentation of the `Observable` trait explains the difference.

      There is also a non-breaking change that we should mention in What's new: we deprecated the method `org.mongodb.scala.Observable.completeWithUnit`, and plan to remove it in a major release.

      Show
      There are multiple changes that break compile-time compatibility (the source code will likely have to be changed to work the the upgraded driver version). Let's mention them in What's new: `org.reactivestreams.Publisher [Void] ` is no longer automatically convertible to `org.mongodb.scala.SingleObservable [Void] `, because we removed the `org.mongodb.scala.ObservableImplicits.ToSingleObservableVoid` implicit class. Our API no longer exposes `org.mongodb.scala.Observable [Void] `. Instead, it exposes `org.mongodb.scala.Observable [Unit] `. The documentation of the `Observable` trait explains the difference. There is also a non-breaking change that we should mention in What's new: we deprecated the method `org.mongodb.scala.Observable.completeWithUnit`, and plan to remove it in a major release.

      In 5.0.0 for the Scala driver use Observable[Unit] instead of Observable[Void] to allow for composable Observables.

      -------

      Was:

      mongo-scala-driver: 4.3.1

      The implementation of MapObservable and FlatMapObservable in the scala driver can lead to unexpected results with `Publisher[Void]`.

      Since Void is not instantiable, the impact on the monadic functions can be missed and lead to bugs. i.e. map/flatmap called on a `Publisher[Void]` will never be invoked.

      This may lead to bugs in clients which are not aware of this. For example

      val obs: Observable[List] = 
        for {
           _ <- session.commitTransaction() // Publisher[Void]
           _ = println("Transaction committed") // never seen
       } yield List(1, 2, 3) // never reached
      

      will result in an empty List.

      while we can work around this by wrapping every Publisher[Void] with our `completeWith(obs, ()): Observable[Unit]`
      where

      def completeWith[A](obs: Observable[Void], f: => A): Observable[A] =
         new Observable[A] {
          override def subscribe(observer: Observer[_ >: A]): Unit =
             obs.subscribe(
                new Observer[Void] {
                  override def onError(throwable: Throwable): Unit =
                  observer.onError(throwable)
      
                  override def onSubscribe(subscription: Subscription): Unit =
                     observer.onSubscribe(subscription)
      
                   override def onComplete(): Unit = {
                     observer.onNext(f)
                     observer.onComplete()
                  }
      
                  override def onNext(tResult: Void): Unit =
                    ??? // by definition never called
           }
         )
       } 
      

      It would seem safer for clients if the MapObservable/FlatMapObservables threw exceptions if onComplete was called without calling onNext.

      An alternative may be to replace occurences of `Publisher[Void]` with `Publisher[Unit]` so that clients can use map/flatMap to react to completion (rather than being forced to wrap or use the reactive API (e.g. `obs.subscribe` )

       

            Assignee:
            valentin.kovalenko@mongodb.com Valentin Kavalenka
            Reporter:
            colin.fairless@digital.hmrc.gov.uk Colin Fairless
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: