Scala's Future and ExecutionContext Execution - scala

Let's say I have the following set of code that does something in a Future:
1 to 10 foreach {
case x => Future { x + x }
}
Assuming that I give the default ExecutionContext to this piece of code, I know what happens in the background, but what I want to know is how is the handling of the Future actually done? I mean there should be some thread or a set of threads that should potentially be waiting for the Future to finish? Are these threads blocked? blocked in the sense where they are literally waiting for the Future to finish?
Now in the following scenario:
val x: Future[MyType] = finishInSomeFuture()
Assuming that x has a timeout that I can call like this:
Future {
blocking {
x.get(3, TimeOut.SECONDS)
}
}
Am I really blocking? Is there a better way to timeout asynchronously?
EDIT: How different or how better is the following Timeout better than the blocking context that I defined above?
object TimeoutFuture {
def apply[A](timeout: FiniteDuration)(block: => A): Future[A] = {
val prom = promise[A]
// timeout logic
Akka.system.scheduler.scheduleOnce(timeout) {
prom tryFailure new java.util.concurrent.TimeoutException
}
// business logic
Future {
prom success block
}
prom.future
}
}

Let's say I have the following set of code that does something in a Future:
1 to 10 foreach {
case x => Future { x + x }
}
...
Your piece of code creates ten Futures that are immediately set for execution using threads provided by implicit ExecutionContext. As you don't store the references to your futures, and don't await for their execution, your main thread (where your foreach is defined) doesn't block and continues its execution immediately. If that piece of code was in the end of the main method, then, depending on whether ThreadFactory in ExecutionContext produced daemon threads program may exit without waiting on Futures to finish.
Now in the following scenario:
val x: Future[MyType] = finishInSomeFuture()
Assuming that x has a timeout that I can call like this:
Future {
blocking {
x.get(3, TimeOut.SECONDS)
}
}
Am I really blocking? Is there a better way to timeout asynchronously?
You probably meant Await.result instead of x.get:
def inefficientTimeoutFuture[T](f:Future[T], x:Duration) = Future { Await.result(f, x) }
In this case future f will be calculate in separate thread, while additional thread will be blocked waiting for the calculation of f.
Using scheduler to create TimeoutFuture is more efficient, as schedulers usually share fixed amount of threads (often one), while blocking in Await.result will always require additional thread to block.
I would like to know how I could timeout without blocking?
Using scheduler to create TimeoutFuture allows you to timeout operation without blocking. You are wrapping your Future in timeout helper, and the new Future either completes successfully or fails due to timeout (whatever comes first). The new Future has the same asynchronous nature and it's up to you how to use it (register onComplete callbacks or synchronously wait for result, blocking main thread).
UPD I'll try to clarify some fundamental things about multithreading and blocking.
Right now asynchronous non-blocking approach is the trend, but you have to understand what blocking means and why it should be avoided.
Each thread in Java comes at the cost. First, it's relatively expensive to create new Thread (that's why thread pools exist) and second, it consumes memory. Why not CPU? Because your CPU resources are limited by the number of cores you have. It doesn't matter how many active threads you have, your parallelism level will always be capped by number of cores. And if thread is inactive (blocked) it doesn't consume CPU.
In contemporary java applications you can create fairly large number of threads (thousands of them). The problem is that in some cases you can't predict how many threads you're gonna need. That's when asynchronous approach comes into play. It says: instead of blocking current thread while some other thread(s) do their job let's wrap our next steps in callback and return current thread to the pool, so it can do some other useful work. So almost all threads are busy doing actual work instead of just waiting and consuming memory.
Now to the example of the timer. If you use netty-based HashedWheelTimer you can have it backed by single thread and have thousands of events scheduled. When you create Future that is blocked waiting for timeout you occupy one thread per "schedule". So if you have thousand timeouts scheduled, you'll end up with thousand blocked thread (which again consume memory, not cpu).
Now your "main" future (that you want to wrap in timeout) doesn't have to block the thread either. For example, if you perform synchronous http request inside the future, your thread will be blocked, but if you use netty-based AsyncHttpClient (for example), you can use a promise-based future that doesn't occupy the thread. And in this case you can have small fixed number of threads that process any number of requests (hundreds of thousands).
UPD2
But there should be some thread that should be blocking even in case of the Timer as it has to wait for the Timeout millis. So what and where is the benefit? I still block, but may be I block less in the Timer case or?
This is true only for one particular scenario: when you have main thread that waits for asynchronous task to complete. In this case you're right, there is no way to wrap operation in timeout without blocking main thread. And it doesn't make any sense to use Timers in this case. You just need additional thread to perform your operation, while main thread waits for result or timeout.
But usually Futures are used in more complex scenarios, where there is no "main" thread. For example, imagine asynchronous webserver, request comes in, you create Future to process it and register callback to reply. No "main" thread to wait for anything.
Or another example, you want to make 1000 requests to external service with individual timeouts and then gather all results in one place. If you have asynchronous client for that service, you create that 1000 requests, wrap them in asynchronous timeouts and then combine into one Future. You can block main thread to wait for that future to complete or register callback to print result, but you don't have to create 1000 threads just to wait for each individual request to complete.
So, the point is: if you already have synchronous flow and you want to wrap some part of it in timeout, the only thing you can do is to have your current thread blocked until other thread(s) perform the job.
If you want to avoid blocking, you need to use asynchronous approach from the start.

Related

When to use scala.concurrent.blocking?

I am asking myself the question: "When should you use scala.concurrent.blocking?"
If I understood correctly, the blocking {} only makes sense to be used in conjunction with the ForkJoinPool. In addition docs.scala-lang.org highlights, that blocking shouldn't be used for long running executions:
Last but not least, you must remember that the ForkJoinPool is not designed for long-lasting blocking operations.
I assume a long running execution is a database call or some kind of external IO. In this case a separate thread pools should be used, e.g. CachedThreadPool. Most IO related frameworks, like sttp, doobie, cats can make use of a provided IO thread pool.
So I am asking myself, which use-case still exists for the blocking statement? Is this only useful, when working with locking and waiting operations, like semaphores?
Consider the problem of thread pool starvation. Say you have a fixed size thread pool of 10 available threads, something like so:
implicit val myFixedThreadPool =
ExecutionContext.fromExecutor(Executors.newFixedThreadPool(10))
If for some reason all 10 threads are tied up, and a new request comes in which requires an 11th thread to do its work, then this 11th request will hang until one of the threads becomes available.
blocking { Future { ... } } construct can be interpreted as saying please do not consume a thread from myFixedThreadPool but instead spin up a new thread outside myFixedThreadPool.
One practical use case for this is if your application can conceptually be considered to be in two parts, one part which say in 90% of cases is talking to proper async APIs, but there is another part which in few special cases has to talk to say a very slow external API which takes many seconds to respond and which we have no control over. Using the fixed thread pool for the true async part is relatively safe from thread pool starvation, however also using the same fixed thread pool for the second part presents the danger of the situation where suddenly 10 requests are made to the slow external API, which now causes 90% of other requests to hang waiting for those slow requests to finish. Wrapping those slow requests in blocking would help minimise the chances of 90% of other requests from hanging.
Another way of achieving this kind of "swimlaning" of true async request from blocking requests is by offloading the blocking request to a separate dedicated thread pool to be used just for the blocking calls, something like so
implicit val myDefaultPool =
ExecutionContext.fromExecutor(Executors.newFixedThreadPool(10))
val myPoolForBlockingRequests =
ExecutionContext.fromExecutor(Executors.newFixedThreadPool(20))
Future {
callAsyncApi
} // consume thread from myDefaultPool
...
Future {
callBlockingApi
}(myPoolForBlockingRequests) // consume thread from myPoolForBlockingRequests
I am asking myself the question: "When should you use scala.concurrent.blocking?"
Well, since that is mostly useful for Future and Future should never be used for serious business logic then never.
Now, "jokes" aside, when using Futures then you should always use blocking when wrapping blocking operations, AND receive a custom ExecutionContext; instead of hardcoding the global one. Note, this should always be the case, even for non-blocking operations, but IME most folks using Future don't do this... but that is another discussion.
Then, callers of those blocking operations may decide if they will use their compute EC or a blocking one.
When the docs mention long-lasting they don't mean anything specific, mostly because is too hard to be specific about that; is context / application specific. What you need to understand is that blocking by default (note the actual EC may do whatever they want) will just create a new thread, and if you create a lot of threads and they take too long to be released you will saturate your memory and kill the program with an OOM error.
For those situations, the recommendation is to control the back pressure of your app to avoid creating too many threads. One way to do that is to create a fixed thread pool for the maximum number of blocking operations you will support and just enqueue all other pending tasks; such EC should just ignore blocking calls. You may also just have an unbound number of threads but manage the back pressure manually in other parts of your code; e.g. with an explicit Queue, this was common advice before: https://gist.github.com/djspiewak/46b543800958cf61af6efa8e072bfd5c
However, having blocked threads is always hurtful for the performance of your app, even if the compute EC is not blocked. The latest talks by Daniel explain those in detail: "The case for effect systems" & "Threads at scale".
So the ecosystem is pushing hard the state of the art to avoid that at all costs but is not a simple task. Still, runtimes like the ones provided by cats-effect or ZIO are optimized to handle blocking tasks the best they can as of today, and will probably improve during this and next years.

asyncio: 50ms delay between put_nowait and get to/from a queue

I have a python asyncio application, with several coroutines being run within a single thread. Some data is being passed using queues.
The queue consumer looks like this:
async def queue_consumer(q):
"""Consume from an asyncio.Queue, making it an async iterable"""
while True:
try:
e = await q.get()
yield e
except:
continue
the consumer is being pulled from with async for.
In this particular case the coroutine which consumes from a specific queue sequentially calls some code which puts data into its queue with put_nowait.
EDIT: In this particular case coroutine A, which is listening for inbound network traffic, puts message into queue of coroutine B.
I have noticed that there is a consistent ~50ms delay between a call to put_nowait in coroutine A and then the data being processed as a result of pulling it from queue async iterable in coroutine B.
I suspect it might have something to do with some asyncio internal polling resolution, but I am not sure, not I would suspect where such configuration could be modified.
I would be very much interested in increasing event polling frequency in the asyncio loop, hence, decreasing observed delay between put_nowait and get to/from a queue between coroutines. Maybe also there's a way to hint asyncio framework to process items from the queue earlier?
NB: the application I am working with is not doing any computationally demanding work.
It turns out the problem was caused by my app doing some UI updates with prompt_toolkit. I tracked this down by placing some measurements within _run_once. Anyway, the queue was not being processed because the event loop was busy executing some UI code that I did not expect to take so much time.

How risky is it to call Await.result on db calls

When using phantom how dangerous is it to be following this pattern in db calls:
Await.result(dbOperationFut, 30.seconds)
This isn't really phantom specific but it is the scala driver being used.
I am weary of this pattern because of the potential GC pause that might last for over x seconds. How many seconds is safe given GC pauses?
I am personally in favor of using for-comp and not blocking like this, but just want to know if this is a REALLY bad practice or it is fine.
Context: This would be for akka based applications (akka, akka http)
Thoughts?
Becareful with Await.result
Note this applies for both Akka and play apps
Await.result should be used very carefully only when it is absolutely necessary.
Await.result blocks the thread in which it is running until the given duration. Blocking the thread will waste the precious computation resource because that thread will not be able to do any useful computation like handling the new request or number crunching in an algorithm etc.
So, Avoid using the Await.result as much as possible.
But, when do we use it (Await.result) ?
Here is one of the typical use case for using Await.result.
Lets say you have written a program containing main thread and all the computation inside the main thread is asynchronous. Now once you start the asynchronous computation inside the main thread. Some one has to stop the main thread from existing till the asynchronous computation finishes, if not the program stops running and you cannot see the result of the asynchronous computation.
When an application begins running, there is one non-daemon thread, whose job is to execute main(). JVM will not exit by itself until and unless non-daemon threads are completed.
object Main {
def main(args: Array[String]): Unit = {
import scala.concurrent.Future
import scala.concurrent.duration._
val f = Future { //do something }
//stop main thread till f completes
Await.result(f, 10 seconds)
}
}
Future uses daemon threads for running. So daemon threads cannot stop the JVM from shutting down. So JVM shuts down even if non-daemon threads are running.
In the above case there is no other way expect stopping (blocking) the main thread till the computation f completes if not main thread exits and computation stops.
In most of the cases you do not need to use Await.result and simple Future composition using map and flatMap would suffice.
Risks of using Await.result (In general all blocking code)
Running out of threads in event based model
In event based model you will quickly run out of threads if you have blocking code which takes long time to return. In playframework any blocking call could decrease the performance of the application and app will becomes dead slow as it runs out of threads.
Running out of memory in non-event based models
In thread per request models. When you have blocking calls which take long time to exit/return.
case 1: If you have fixed thread pool then application might run out of threads.
case 2: If you have dynamically growing thread pool then your application will suffer from too much context switching overhead and also will run out of memory because of too many blocked threads in memory.
In all of the cases no useful work is done expect for waiting for some IO or some other event.

CyclicBarrier and CountDownLatch?

What is the difference between CyclicBarrier and CountDownLatch? I thnik there is subtle difference, as both looks same.
Please let me know if I am wrong and also explain same.
A CountDownLatch is used for one-time synchronization. While using a CountDownLatch, any thread is allowed to call countDown() as many times as they like. Threads which called await() are blocked until the count reaches zero because of calls to countDown() by other unblocked threads. The javadoc for CountDownLatch states:
The await methods block until the current count reaches zero due to
invocations of the countDown() method, after which all waiting threads
are released and any subsequent invocations of await return
immediately.
...
Another typical usage would be to divide a problem into N parts,
describe each part with a Runnable that executes that portion and
counts down on the latch, and queue all the Runnables to an Executor.
When all sub-parts are complete, the coordinating thread will be able
to pass through await. (When threads must repeatedly count down in
this way, instead use a CyclicBarrier.)
In contrast, the cyclic barrier is used for multiple sychronization points, e.g. if a set of threads are running a loop/phased computation and need to synchronize before starting the next iteration/phase. As per the javadoc for CyclicBarrier:
The barrier is called cyclic because it can be re-used after the
waiting threads are released.
Unlike the CountDownLatch, each call to await() belongs to some phase and can cause the thread to block until all parties belonging to that phase have invoked await(). There is no explicit countDown() operation supported by the CyclicBarrier.

How does I/O work in Akka?

How does the actor model (in Akka) work when you need to perform I/O (ie. a database operation)?
It is my understanding that a blocking operation will throw an exception (and essentially ruin all concurrency due to the evented nature of Netty, which Akka uses). Hence I would have to use a Future or something similar - however I don't understand the concurrency model.
Can 1 actor be processing multiple message simultaneously?
If an actor makes a blocking call in a future (ie. future.get()) does that block only the current actor's execution; or will it prevent execution on all actors until the blocking call has completed?
If it blocks all execution, how does using a future assist concurrency (ie. wouldn't invoking blocking calls in a future still amount to creating an actor and executing the blocking call)?
What is the best way to deal with a multi-staged process (ie. read from the database; call a blocking webservice; read from the database; write to the database) where each step is dependent on the last?
The basic context is this:
I'm using a Websocket server which will maintain thousands of sessions.
Each session has some state (ie. authentication details, etc);
The Javascript client will send a JSON-RPC message to the server, which will pass it to the appropriate session actor, which will execute it and return a result.
Execution of the RPC call will involve some I/O and blocking calls.
There will be a large number of concurrent requests (each user will be making a significant amount of requests over the WebSocket connection and there will be a lot of users).
Is there a better way to achieve this?
Blocking operations do not throw exceptions in Akka. You can do blocking calls from an Actor (which you probably want to minimize, but thats another story).
no, 1 actor instance cannot.
It will not block any other actors. You can influence this by using a specific Dispatcher. Futures use the default dispatcher (the global event driven one normally) so it runs on a thread in a pool. You can choose which dispatcher you want to use for your actors (per actor, or for all). I guess if you really wanted to create a problem you might be able to pass exactly the same (thread based) dispatcher to futures and actors, but that would take some intent from your part. I guess if you have a huge number of futures blocking indefinitely and the executorservice has been configured to a fixed amount of threads, you could blow up the executorservice. So a lot of 'ifs'. a f.get blocks only if the Future has not completed yet. It will block the 'current thread' of the Actor from which you call it (if you call it from an Actor, which is not necessary by the way)
you do not necessarily have to block. you can use a callback instead of f.get. You can even compose Futures without blocking. check out talk by Viktor on 'the promising future of akka' for more details: http://skillsmatter.com/podcast/scala/talk-by-viktor-klang
I would use async communication between the steps (if the steps are meaningful processes on their own), so use an actor for every step, where every actor sends a oneway message to the next, possibly also oneway messages to some other actor that will not block which can supervise the process. This way you could create chains of actors, of which you could make many, in front of it you could put a load balancing actor, so that if one actor blocks in one chain another of the same type might not in the other chain. That would also work for your 'context' question, pass of workload to local actors, chain them up behind a load balancing actor.
As for netty (and I assume you mean Remote Actors, because this is the only thing that netty is used for in Akka), pass of your work as soon as possible to a local actor or a future (with callback) if you are worried about timing or preventing netty to do it's job in some way.
Blocking operations will generally not throw exceptions, but waiting on a future (for example by using !! or !!! send methods) can throw a time out exception. That's why you should stick with fire-and-forget as much as possible, use a meaningful time-out value and prefer callbacks when possible.
An akka actor cannot explicitly process several messages in a row, but you can play with the throughput value via the config file. The actor will then process several message (i.e. its receive method will be called several times sequentially) if its message queue it's not empty: http://akka.io/docs/akka/1.1.3/scala/dispatchers.html#id5
Blocking operations inside an actor will not "block" all actors, but if you share threads among actors (recommended usage), one of the threads of the dispatcher will be blocked until operations resume. So try composing futures as much as possible and beware of the time-out value).
3 and 4. I agree with Raymond answers.
What Raymond and paradigmatic said, but also, if you want to avoid starving the thread pool, you should wrap any blocking operations in scala.concurrent.blocking.
It's of course best to avoid blocking operations, but sometimes you need to use a library that blocks. If you wrap said code in blocking, it will let the execution context know you may be blocking this thread so it can allocate another one if needed.
The problem is worse than paradigmatic describes since if you have several blocking operations you may end up blocking all threads in the thread pool and have no free threads. You could end up with deadlock if all your threads are blocked on something that won't happen until another actor/future gets scheduled.
Here's an example:
import scala.concurrent.blocking
...
Future {
val image = blocking { load_image_from_potentially_slow_media() }
val enhanced = image.enhance()
blocking {
if (oracle.queryBetter(image, enhanced)) {
write_new_image(enhanced)
}
}
enhanced
}
Documentation is here.