3
votes

I (a newbie) am testing my concepts about Scala's Futures and the right patterns to use them.

The premise
Scala's futures are blocks of code to be executed asynchronously. So, the main thread creates one or more such futures, installs onSuccess() [note: equally applicable to OnComplete/onFailure] callbacks and proceeds. The callbacks are executed as and when the futures complete their runs.

Presumably, these callbacks generate results which are supposed to be used by the main thread. The results are stored in a Try[T] container, with a write-once/read-many constraint. The main (or any other thread but that is not the point) decide when to peak in the container and collect the results for further processing.

Whichever discussion/blog/API I have laid my eyes on so far, mentions the fact that main thread doesn't have to wait: it can carry on doing its own thing, allowing the futures to be executed in parallel and be ready with the result.

Question

But my question is: in the simplest case, where it has finished doing whatever it is doing, the main thread will have to wait for the callbacks to finish, will it not? And, because there is no interruption mechanism provided which can indicate that the future has finished execution, the main thread has no option but to 'wait' (possibly with a time-limit) for the result to be ready? In other words, in an application, where futures are employed, a wait is ultimately unavoidable, isn't it?

Note
I understand that we can chain the futures, using combinators or Promise (and there are other patterns too), to avoid this issue altogether. But, I am trying to clarify my concept that under certain cases, using futures doesn't obviate the need to wait for them to finish.

Is it too elementary a question? Is it showing a big void in my understanding?

1
Note that there is no need in "main thread" at all, you could use only futures and actors without "main thread" and all code will be in callbacks. For instance it play framework there is no "main thread". You could also check in main thread if future is completed and that perform some actions without waiting.senia
You presume that the thread of execution / execution context that initiates a Future is the ultimate consumer of it. That is not necessarily so. However, whatever computation does consume that value must wait for it, of course, but even that need not be done by waiting. As you observe, it can be delivered via one of the completion handlers. It is in fact possible to write systems that never Await a Future, but rather do everything asynchronously.Randall Schulz
Why would the main thread wait for futures to finish? Unless it is doing an await or something there would be no need. I think the confusion you have here is probably because you expect that JVM will only shutdown when main thread exists?Jatin
@senia, I understand that a 'main thread' is not necessary. The app can work on the basis of a bunch of well-orchestrated callbacks. Agreed. Mine was more of theoretical, conceptual Q.Nirmalya
@RandallSchulz, That presumption was to make a basis for my question. Almost always, this is not the case. Agreed. Say, the main thread needs to collect last 10 tweets from 3 different friends. So, it fires 3 futures, each meant for 1 friend! The collection cannot be formed till three futures finish, right? So, main thread has no option but to wait for all three to be done. That was my point.Nirmalya

1 Answers

3
votes

It would be useful to understand the theoretical difference between Await and async. These are known as blocking and non-blocking respectively.

Blocking

A blocking computation is much like a while loop.

while(!done) {
  if (isDone) {
    // do whatever
    done = true
  }
}

This is synchronous blocking computation. The Thread can't do anything else until the blocking action is complete as its constantly checking for the action.

You only really have as many threads as processors on the machine. Hopefully you can see how they can quickly be fully occupied and a giant FIFO queue of "things to do" is formed.

Non-blocking

In essence, the concept is very simple. Instead of continuously checking if something is done, the check is done at given time intervals. The Future will be checked for completion every 100ms(let`s say).

The awesome thing is during every one of those 100ms breaks, the Thread is free to do something else. That's why you get superior performance from async things.

Bottom line

It's physically possible for the processors to do more things in a given time interval. It's a very simple syllogism.

Say you and your friend arrange to meet for coffee at 3PM. He doesn't show up.

You can either sit in the coffee shop relentlessly cursing or you can go home and bake cookies. While the cookies are baking, you check your phone every 5 minutes until he eventually texts and then you meet up.

In scenario 1, you are angry and haven't done much all day.

In scenario 2, you are delighted by your culinary success and in a great mood to see a friend.