My scenario is, I have multiple API's call to be made and each of them will require to use data from previous call.
Now let's suppose I made a API call with future, and return response of the first call, I am not able to call next API from within Oncomplete of first call.
You can link Futures with flatMap function
def firstApiCall(): Future[FirstRes]
def secondApiCall(firstRes: FirstRes): Future[SecondRes]
def combinedCall()(implicit ec: ExecutionContext): Future[SecondRes] = firstApiCall.flatMap(res => secondApiCall(res))
You could use flatMap or the cleaner alternative to sequencing a bunch of of futures, which is to use the for yield syntax. It's just compile time sugar that will internally transform itself into flatMap and map and withFilter method calls, but it's generally cleaner and easier to read.
import scala.concurrent.ExecutionContext.Implicits.global
for {
first <- firstApiCall()
second <- secondApiCall(first)
} yield second
Related
I'm pretty new to Scala and I'd like to know if there's some way to create a dummy Future object to simulate isCompleted to false. I need this for testing purposes.
Currently what I'm using to have a dummy Future[Int] is this:
Future({
while (true) {}
1
})
which is very ugly.
EDIT
I have an object with a variable x which is a Option[Future[Int]]. In the same object I have method that checks whether x is different from None, and if it is it checks whether it is completed or not. If the future is not completed yet it avoids calling a method on an external helper object. This external helper object during testing is mocked and I'm checking that it is not being called. To achieve this I currently set the x variable to the Future written above.
Also, there is simple:
val f: Future[Int] = Future.never
Use Future.never, also suggested first by this answer:
val f: Future[Int] = Future.never
You should avoid using a promise (as this answer initially suggested):
val f: Future[Int] = Promise[Int]().future
since it can lead to memory leaks if the future is subscribed to, see here for a description.
As I know, Future is read-only and Promise is write-once data structure.
We need a Promise to complete a Future
For example,
object Lie extends Throwable
val lie = Future { throw Lie }
val guess = Promise[String]()
lie.onComplete { case Success(s) => guess.success("I knew it was true!")
case Failure(t) => guess.failure("I knew it was lie")}
// return type: Unit
guess.future.map(println)
// res12: scala.concurrent.Future[Unit] = List()
// I knew it was lie!
// Requires Promise to chain Future with exception
But, I can't understand why we need to have both Future and Promise
I guess Promise is required because of Future.onComplete signature
Since Future.onComplete return type is Unit,Future with possible exceptions cannot be chained
I assume Promise was introduced to overcome this limitation
But why not just change the signature of Future.onComplete ?
Changing the return type of Future.onComplete as Future[T] will enable chaining on Future with exception
and then, Future does not need Promise
For example, code above can be changed into
val lie = Future { throw Lie }
lie.onComplete {
case Success(s) => "I knew it was true!"
case Failure(t) => "I knew it was lie!"
}.map(println)
//onComplete return type is Future[String]
My question is
1) am I right? does Future not need Promise , If onComplete signature is changed from Unit to Future[T]?
2) Why Future and Promise are divided in the first place ?
UDPATE
Thanks to the repliers, Now I understand the purpose of Promise. It wasn't actually for Future chaining
If I may, can I ask you
Why onComplete returns Unit ??
It can actually return Future[T] to enable chaining Future easily
For example
Future { throw Error }.onComplete {
case Success(s) => "Success"
case Failure(t) => throw Error
}.onComplete {
case Success(s) => "Success"
case Failure(t) => throw Error
}. ...
Future.apply[T](block: => T): Future[T] is syntactic sugar for Future.unit.map(_ => block)[1]
A Future represents a value which may or may not be currently available.
A Promise represents the obligation to provide such a value at some point.
Having separate entities for Future (for reads) and Promise (for writes) means that it is easy to reason about capabilities:
When a Future is a parameter, it is a request to have some value at some point and when it is used as a return type, it's a response which may not be currently available.
When a Promise is a parameter, it is the "consumption" of responsibility of producing some value at some point, and when it is used as a return type it is the "production" of responsibility to produce the value at some point.
All in all, being able to reason about capabilities, especially in asynchronous, or even concurrent programs, is extremely valuable.
Most of the time Promises need not be used, since that is transparently handled by the Future-combinators—but when integrating with third party software or networking libraries it can be extremely useful.
For more information about interesting new features in Scala 2.12, have a look here.
1: Where Future.unit
is defined as:
val unit: Future[Unit] = Future.successful(())
am I right? does Future not need Promise , If onComplete signature is
changed from Unit to Future[T]?
You're mixing things up a little. Let's clarify.
A Future[T] represents a computation which will complete in the future. That is, you pass Future.apply a function which will execute on a thread assigned by some ExecutionContext you define.
Now, on the other hand, a Promise[T] is a way to create a Future[T], without actually creating a Future[T]. A good example for this would be the Future.successful method (which will internally consume Promise.successful):
def successful[T](result: T): Future[T] = Promise.successful(result).future
This requires no ExecutionContext and no queuing if any additional resources. It's merely a convenience wrapper that allows you to "artificially" create a Future[T].
No.
Futurecannot cover the use cases of Promise. Promise has its own value. You cannot replace Future with Promise.
Future represents a computation which is available at a later point of time. You can get the result using onComplete once the future execution is complete and you can compose futures using map, flatMap, recover and recoverWith.
Promise is one time write container, clients can subscribe to the container. When subscribed client gets a future to wait until value is written into that container called promise.
Future is read-only
You cannot use future as one time write container. You can only read from future.
But Promise is different.
What if you want to give user something, which you do not have right now but you think you will have it soon ?
That means you are promising user something which you do not have right now.
So you want to keep the user waiting till you have the thing which you will give it to user. Thats when you do p.future and generate a future so that user can wait for the result using the future.
Once you have the result which you promised to give the user, You give to user by making the future a success or failure when something bad happens (i.e by doing p.complete).
Even if onComplete return type is changed to Future[T]. Future cannot act like or serve purpose of Promise.
Creating future using Future companion object
Future can be created by using Future.apply also. In this case future created would be complete once the computation inside the future finishes.
Future is used to subscribe to the result of the time-consuming computation, whereas Promise can be a publish and subscribe model.
I'm attempting to implement an API method (AsyncWriteJournal.asyncWriteMessages – part of Akka 2.4's persistence API) that requires me to return a Future[Seq[Try[Unit]]]. The idea being that a number of operations can be performed any of which may individually succeed or fail, the future can be used to await completion of all the operations. The future itself can optionally succeed even there's a certain class of failure in individual operations.
The underlying operations I'm using (Rediscala) return Futures but I'm stuck trying to transform a Seq[Future[Unit]] into the required return type. I can do it using Promise on each operation and tying them together with Future.sequence but then the resulting future fails if any of the operations fails which is not the correct behavior
Is this what you wanted?
def transform(ops: Seq[Future[Unit]])(implicit ec: ExecutionContext): Future[Seq[Try[Unit]]] =
Future.sequence(ops.map (
_.map(Success(_)).recover {
case ex => Failure(ex)
}
))
What about if you turn a possibly failing future into a future that will succeed in any case, and then use Future.sequence?
I know a lot of reasons for Scala Future to be better. Are there any reasons to use Twitter Future instead? Except the fact Finagle uses it.
Disclaimer: I worked at Twitter on the Future implementation. A little bit of context, we started our own implementation before Scala had a "good" implementation of Future.
Here're the features of Twitter's Future:
Some method names are different and Twitter's Future has some new helper methods in the companion.
e.g. Just one example: Future.join(f1, f2) can work on heterogeneous Future types.
Future.join(
Future.value(new Object), Future.value(1)
).map {
case (o: Object, i: Int) => println(o, i)
}
o and i keep their types, they're not casted into the least common supertype Any.
A chain of onSuccess is guaranteed to be executed in order:
e.g.:
f.onSuccess {
println(1) // #1
} onSuccess {
println(2) // #2
}
#1 is guaranteed to be executed before #2
The Threading model is a little bit different. There's no notion of ExecutionContext, the Thread that set the value in a Promise (Mutable implementation of a Future) is the one executing all the computations in the future graph.
e.g.:
val f1 = new Promise[Int]
f1.map(_ * 2).map(_ + 1)
f1.setValue(2) // <- this thread also executes *2 and +1
There's a notion of interruption/cancellation. With Scala's Futures, the information only flows in one direction, with Twitter's Future, you can notify a producer of some information (not necessarily a cancellation). In practice, it's used in Finagle to propagate the cancellation of a RPC. Because Finagle also propagates the cancellation across the network and because Twitter has a huge fan out of requests, this actually saves lots of work.
class MyMessage extends Exception
val p = new Promise[Int]
p.setInterruptHandler {
case ex: MyMessage => println("Receive MyMessage")
}
val f = p.map(_ + 1).map(_ * 2)
f.raise(new MyMessage) // print "Receive MyMessage"
Until recently, Twitter's Future were the only one to implement efficient tail recursion (i.e. you can have a recursive function that call itself without blowing up you call stack). It has been implemented in Scala 2.11+ (I believe).
As far as I can tell the main difference that could go in favor of using Twitter's Future is that it can be cancelled, unlike scala's Future.
Also, there used to be some support for tracing the call chains (as you probably know plain stack traces are close to being useless when using Futures). In other words, you could take a Future and tell what chain of map/flatMap produced it. But the idea has been abandoned if I understand correctly.
What is in your view the best scala solution for the case that you have some plain chain of synchronous function calls, and you need to add an asynchronous action in the middle of it without blocking?
I think going for futures entails refactoring existing code to callback spaghetti, tethering futures all the way through the formerly synchronous chain of function calls, or polling on the promise every interval, not so optimal but maybe I am missing some trivial/suitable options here.
It may seem that refactoring for (akka) actors, entail a whole lot of boilerplate for such a simple feat of engineering.
How would you plug in an asynchronous function within an existing synchronous flow, without blocking, and without going into a lot of boilerplate?
Right now in my code I block with Await.result, which just means a thread is sleeping...
One simple dirty trick:
Let's say you have:
def f1Sync: T1
def f2Sync: T2
...
def fAsynchronous: Future[TAsync]
import scala.concurrent.{ Future, Promise }
object FutureHelper {
// A value class is much cheaper than an implicit conversion.
implicit class FutureConverter[T](val t: T) extends AnyVal {
def future: Future[T] = Promise.successful(t).future
}
}
Then you can for yield:
import FutureHelper._
def completeChain: Future[Whatever] = {
for {
r1 <- f1Sync.future
r2 <- f2Sync.future
.. all your syncs
rn <- fAsynchronous // this should also return a future
rnn <- f50Sync(rn).future// you can even pass the result of the async to the next function
} yield rn
}
There is minimal boilerplate of converting your sync calls to immediately resolved futures. Don't be tempted to do that with Future.apply[T](t) or simply Future(a) as that will put daemon threads onto the executor. You won't be able to convert without an implicit executor.
With promises you pay the price of 3, 4 promises which is negligible and you get what you want. for yield acts as a sequencer, it will wait for every result in turn, so you can even do something with your async result after it has been processed.
It will "wait" for every sync call to complete as well, which will happen immediately by design, except for the async call where normal async processing will be automatically employed.
You could also use the async/await library, with the caveat that you wind up with one big Future out of it that you still have to deal with:
http://docs.scala-lang.org/sips/pending/async.html
But, it results in code almost identical to the sychronous code; where you were previously blocking, you add an:
await { theAsyncFuture }
and then carry on with synchronous code.