1
votes

I would like to clear up what it means to be a asynchronous/synchronous and blocking/non-blocking operations in Scala Play using Scala's Future.

So we can have:

  1. Asynchronous and non-blocking
  2. Asynchronous and blocking
  3. Synchronous and non-blocking
  4. Synchronous and blocking

In the Play documentation it says that all operations are asynchronous. But I would like to know how the following would be classed:

If I call an external web service and I have to wait for the response then is this considered to be a asynchronous and blocking operation? For example:

def externalWebCall(url : String): Future[SomeData]
def storeData(data : String) : Future[Unit]

for {
data <- externalWebCall(url)
_    <- storeData(data)
} yield(data)

In this example, I don't want storeData to execute until the externalWebCall service has completed. Is the above code the right way to achieve this? If so I think this is asynchronous and blocking.

The initial request that comes to Play service is treated in an asynchronous and non-blocking way according to the documentation. My understanding of this is that when the Play server receives the request it will not block the main thread. It will then service the request and then make a call to the callback of this request and then return the result. Is that correct?

2

2 Answers

2
votes

When people use the term "asynchronous", they usually mean "non-blocking", in the sense that the current execution thread will not stop and wait for the result. In general, synchronous means blocking, asynchronous means non-blocking.

It seems you are confusing "blocking" with "ordering the execution". Your example with the Futures is completely asynchronous, and it equivalent to

val result: Future[Unit] = externalWebCall(url).flatMap(storeData)

storeData can only execute when externalWebCall is done, but any code that would come after val result = ... could also execute before either externalWebCall or storeData. The execution of these methods is wrapped in a Future and run in a different thread, so you have no way of knowing when it will happen. That is what asynchronous means.

1
votes

The terms blocking and asynchronous have different meanings, but are often confused or used interchangeably.

blocking means that the current thread waits for another thread to do something before executing further instructions. The current thread is blocked until the other thread completes and then it can continue.

asynchronous means that an operation happens on another thread while the current thread continues to execute. The current thread initiates an operation but then continues to execute. When the asynchronous operation completes it notifies the current thread by raising an event or calling some event handler function.

Blocking functions look like normal functions and there is not necessarily any indication that the code being called is blocking or non blocking. So a println statement may be blocking for stderr but non-blocking for stdout.

Asynchronous functions will always have a mechanism for being notified of completion of the operation and this will be visible in the interface. In Scala this usually means returning Future[T] rather than T.


In your example, both externalWebCall and storeData are asynchronous because each method returns Future.

storeData takes a data argument that is only available when externalWebCall completes, so these two operations must by definition operate sequentially.