1
votes

I am currently building a Scala play framework app which uses a library that return results as F.Promise (Java Promise). Is there a way to convert F.Promises (https://www.playframework.com/documentation/2.1.0/api/java/play/libs/F.Promise.html) into Scala Promises or get the wrapped Scala Future out of the F.Promise?

The only way I see so far is getting the F.Promise but that is a blocking operation and I would like to continue working asynchronous.

The way descriped in the first answer led me to this code. Unfortunately I dont know how to define this F.Function correctly. The code does not compile.

Answer: So, I finally found out that the F.Promise has a method called wrapped(). And this method gives you a Scala Future back.

2

2 Answers

3
votes

It turns out that the class F.Promise (java.play) has a method called wrapped() which returns the scala.concurrente.Future that is wrapped by the Promise. So all you have to do is calling wrapped on the F.Promise.

val promise: F.Promise[T] = getPromise()
val future : Future[T] = promise.wrapped()
1
votes

Well, since there is no 'standard' for promises or futures in that ecosystem, you'd have to do it manually. There is no concept of 'assimilation' between play promises and scala futures.

Basically, we treat a F.Promise like we'd treat a callback, we convert it to a scala Future by creating a Promise (which, confusingly in scala means "that which creates a Future"). Here is a description of how this works rather than code since I think that would explain the rationale better:

  • Create a new Promise[T] - p
  • Call .map on the F.Promise you have, in the F.Function passed to it, call p success with the value of the promise - effectively resolving the promise.
  • Similarly - call .recover on the promise and inside its handler call p failure with the failure reason.
  • Return p.future, which is a future representing the value p is resolved with - since we mirrored both the success and failure channels this will work.

This is not unlike how you would convert anything else to a scala Future. Converting in the other direction works similarly.