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

Improve map/flatmap of Publisher[Void]

    XMLWordPrintable

Details

    • Improvement
    • Status: Backlog
    • Unknown
    • Resolution: Unresolved
    • None
    • 5.0.0
    • Reactive Streams

    Description

      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` )

       

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              colin.fairless@digital.hmrc.gov.uk Colin Fairless
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated: