blue-sky
blue-sky

Reputation: 53916

Wrap asynchronous code in a blocking call

I'm inserting a record in MongoDB :

val observable: Observable[Completed] = collection.insertOne(doc)

observable.subscribe(new Observer[Completed] {
  override def onNext(result: Completed): Unit = { println("Inserted"); }
  override def onError(e: Throwable): Unit = { println(" \n\nFailed " + e + "\n\n"); fail() }
  override def onComplete(): Unit = { println("Completed"); }
})

The test passes even though the onError callback is invoked. This is because insertOne is an asynchronous method and the test completes before the onError is invoked. I would like to wrap the insertOne method into a blocking call, so subscribe is not invoked until after observable value is set.

Is there an idiomatic method to achieve this is in Scala ?

Upvotes: 1

Views: 293

Answers (1)

Yuval Itzchakov
Yuval Itzchakov

Reputation: 149628

The simplest approach to synchronously block the async operation is using Await.result on a Future. Since MongoCollection.insertOne returns an Observable[Complete], you can use the implicit ScalaObservable.toFuture on it:

val observable = collection.insertOne(doc)
Await.result(observable.toFuture, Duration.Inf)

observable.subscribe(new Observer[Completed] {
  override def onNext(result: Completed): Unit = { println("Inserted"); }
  override def onError(e: Throwable): Unit = { println(" \n\nFailed " + e + "\n\n"); fail() }
  override def onComplete(): Unit = { println("Completed"); }
})

Upvotes: 2

Related Questions