a thread lies in one of the shown states at any instant:
New
Runnable
Blocked
Waiting
Timed Waiting
Terminated
So, what is lifecycle and states of a ZIO fiber?
Is it similar or the same as a thread?
Related
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.
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.
In my scala application I have an actor A that is the child of the guardian actor. The guardian actor has been given a one for all strategy to escalate on children shutdown.
Under various circumstances, the actor A calls context stop self that usually results in the entire application exiting, which is the desired behavior.
However, I recently observed a scenario where context stop self resulted in an error
Failed to run termination callback, due to [Futures timed out after [5000 milliseconds]]
..and the actor system did not shutdown.
The application does sometimes have hundreds of thousands of actors under Actor A, and I wonder if shutting them down caused some sort of timeout in the termination procedure.
Can anyone help me understand why the behavior described above would happen and should I be using context system shutdown instead to shutdown the system?
Is it correct to use Thread.sleep(5000); inside an actor? Does it actualy make an actor sleep for 5 seconds? Is there a simple alternative to make an actor sleep for some seconds?
Anything that blocks a thread is not advised within Akka. If the Actor is configured with a a shared thread pool (default behavior) then using Thread.sleep will withhold a thread from that pool that could be doing work for other Actors.
If one really must block, then an actor may be configured to have its own thread. This can be done by configuring a custom dispatcher for the actor to use, the full details are here.
The recognized alternative to blocking is to schedule a callback to the actor via a timer, for example send a message after 5 seconds..
akkaSystem.scheduler.scheduleOnce(5 seconds, actor, "msgFoo")
The Akka scheduler is documented here: http://doc.akka.io/docs/akka/2.3.6/scala/scheduler.html
If a function in a thread is going to return, how can we describe this behavior.
The thread returns.
The thread is dying.
What's the meaning of "thread is dead"?
In my understanding, threads are basically kernel data structures. You can create and destroy threads through the system APIs. If you just create a thread, start it executing, and it runs out of code, the kernel will probably put it into a non-executing state. In unmanaged code you still have to release that resource.
Then there's the thread pool. In that case, you queue up work to be done by the thread pool, and the platform takes care of picking a thread and executing your work. When the work is complete, the thread is returned to the thread pool. The platform takes care of creating and destroying threads to balance the available threads against the workload and the system resources.
As of Java 1.3 the six-state thread model was introduced. This includes the following states:
Ready-to-run: The thread is created and waiting for being picked for running by the thread scheduler
Running: The thread is executing.
Waiting: The thread is in blocked state while waiting for some external processing to finish (like I/O).
Sleeping: The thread is forced to sleep via .sleep()
Blocked: On I/O: Will move into state 1 after finished (e.g. reading a byte of data). On sync: Will move into state 1 after a lock is acquired.
Dead (Terminated): The thread has finished working and cannot be resumed.
The term "Dead" is rarely used today, almost totally changed to "Terminated". These two are equivalent.
Most thread APIs work by asking the operating system to run a particular function, supplied by you, on your behalf. When this function eventually returns (via for example a return statement or reaching the end of its code) the operationg system ends the thread.
As for "dead" threads - that's not a term I've seen used in thread APIs.