Scala Concurrency: main thread lag - scala

When I start some Scala Futures that perform expensive computations, the main thread starts to lag very badly. I don't use any callbacks just plain:
//got global execution context
for(i <- 0 until NUMBER_OF_FUTURES){
Future{do_work()}
}
What causes the freezes ?
EDIT:
Maybe execution context allows to run Futures on the main thread ?
EDIT2
Execution context I'm using:
private implicit val ec = new ExecutionContext
{
val threadPool = Executors.newSingleThreadExecutor()
def execute(runnable: Runnable) {
threadPool.submit(runnable)
}
def reportFailure(t: Throwable) {}
}

Related

Execution Context not getting shutdown

I am running into a strange problem where the execution context is not getting shut down.I tried with or without await.
import scala.concurrent.ExecutionContext
val customExecutor: ExecutorService =
Executors.newFixedThreadPool(serviceConfig.serviceConf.numberOfThreads)
implicit val customExecutionContext: ExecutionContext =
ExecutionContext.fromExecutorService(
Executors.newFixedThreadPool(10)
)
futureCall() map { result =>
import java.util.concurrent.TimeUnit
customExecutor.shutdown()
customExecutor.awaitTermination(60, TimeUnit.SECONDS)
}
You are waiting for the shutdown inside a thread, but the executor can't shut down while a thread is running so it's not going the happen. So move the awaitTermination outside the map function.
However the real problem is that you are creating two ExecutorServices and stopping the wrong one. If you just pass the service that you created, it terminates as expected:
val customExecutor: ExecutorService =
Executors.newFixedThreadPool(10)
implicit val customExecutionContext: ExecutionContext =
ExecutionContext.fromExecutorService(customExecutor)
futureCall() map { result =>
customExecutor.shutdown()
}
customExecutor.awaitTermination(5, TimeUnit.SECONDS)

Executing More than 3 Futures does not work

I m using dispatch library in my sbt project. When I initialize three future and run them it is working perfectly But I increase one more future then it goes to a loop.
My code:
//Initializing Futures
def sequenceOfFutures() ={
var pageNumber: Int = 1
var list ={Seq(Future{})}
for (pageNumber <- 1 to 4) {
list ++= {
Seq(
Future {
str= getRequestFunction(pageNumber);
GlobalObjects.sleep(Random.nextInt(1500));
}
)
}
}
Future.sequence(list)
}
Await.result(sequenceOfFutures, Duration.Inf)
And then getRequestionFunction(pageNumber) code:
def getRequestionFunction(pageNumber)={
val h=Http("scala.org", as_str)
while(h.isComplete){
Thread,sleep(1500);
}
}
I tried based on one suggestion from How to configure a fine tuned thread pool for futures?
I added this to my code:
import java.util.concurrent.Executors
import scala.concurrent._
implicit val ec = new ExecutionContext {
val threadPool = Executors.newFixedThreadPool(1000);
def execute(runnable: Runnable) {
threadPool.submit(runnable)
}
def reportFailure(t: Throwable) {}
}// Still didn't work
So when I use more than four Futures then it keeps await forever. Is there some solution to fix it?
But it didn't work Could someone please suggest how to solve this issue?

Why future example do not work?

I am reading akkaScala documentation, there is an example (p. 171 bottom)
// imports added for compilation
import scala.concurrent.{ExecutionContext, Future}
import ExecutionContext.Implicits.global
class Some {
}
object Some {
def main(args: Array[String]) {
// Create a sequence of Futures
val futures = for (i <- 1 to 1000) yield Future(i * 2)
val futureSum = Future.fold(futures)(0)(_ + _)
futureSum foreach println
}
}
I run it, but nothing happened. I mean that nothing was in console output. What is wrong?
You don't wait for the future to complete, so you create a race between the program exiting and the futures completing and the side-effect running. On your machine, the future seems to lose the race, on the commenters' who say "it works", the future is winning the race.
You can use Await to block on a future and wait for it to complete. This is something you should only be doing "at the ends of the world", you should very rarely actually be using Await...
// imports added for compilation
import scala.concurrent.{ExecutionContext, Future}
import ExecutionContext.Implicits.global
import scala.concurrent.duration._ // for the "1 second" syntax
import scala.concurrent.Await
class Some {
}
object Some {
def main(args: Array[String]) {
// Create a sequence of Futures
val futures = for (i <- 1 to 1000) yield Future(i * 2)
val futureSum = Future.fold(futures)(0)(_ + _)
// we map instead of foreach, to make sure that the side-effect is part of the future
// and we "await" for the future to complete (for 1 second)
Await.result(futureSum map println, 1 second)
}
}
As others have stated, the issue is the race condition where the futures are competing with the program terminating. The JVM has a concept of daemon threads. It waits for non-daemon threads to terminate but not daemon threads. So if you want to wait for threads to complete, use non-daemon threads.
The way threads are created for scala futures is using an implicit scala.concurrent.ExecutionContext. The one you use (import ExecutionContext.Implicits.global) starts daemon threads. However, it is possible to use non-daemon threads. So if you use an ExecutionContext with non-daemon threads, it will wait, which in your case is reasonable behaviour. Naively:
import scala.concurrent.Future
import scala.concurrent.ExecutionContextExecutor
import scala.concurrent.ExecutionContext
class MyExecutionContext extends ExecutionContext {
override def execute(runnable:Runnable) = {
val t = new Thread(runnable)
t.setDaemon(false)
t.start()
}
override def reportFailure(t:Throwable) = t.printStackTrace
}
object Some {
implicit lazy val context: ExecutionContext = new MyExecutionContext
def main(args: Array[String]) {
// Create a sequence of Futures
val futures = for (i <- 1 to 1000) yield Future(i * 2)
val futureSum = Future.fold(futures)(0)(_ + _)
futureSum foreach println
}
}
Careful with using the above ExecutionContext in production because it doesn't use a thread pool and can create unbounded threads, but the message is: you can control everything about the threads behind Futures through an ExecutionContext. Explore the various scala and akka contexts to find what you need, or if nothing suits, write your own.
Both of the following statement at the end of main function would help your need. As the above answers said, allow the future to complete. Main thread is different from the Future thread, as main completes, it terminates before Future thread.
Thread.sleep(500) //... Simple solution
Await.result(futureSum, Duration(500, MILLISECONDS)) //...have to import scala.concurrent.duration._ to use Duration object.

why the main app doesn't exit when calling a timer.schedule

In the following,it run a calcuation after delay 2 seconds, but when run the app, it never exit. What is the code blocking the app to exit?
object Test extends App{
import scala.concurrent._
import java.util._
import java.util.concurrent.{ TimeUnit }
val timer = new java.util.Timer()
def timeoutFuture[A](v: A, delay: Long, unit: TimeUnit): Future[A] = {
println("inner")
val p = Promise[A]()
println("inner")
timer.schedule(new java.util.TimerTask {
def run() {
p.success(v)
}
}, unit.toMillis(delay))
println("inner")
p.future
}
println("begin")
val x1=timeoutFuture[Int](1+1,2,TimeUnit.SECONDS)
println("end")
println("quit")
}
val timer = new java.util.Timer() will start a TimerThread (which extends a standard Java thread and is implemented as an infinite loop), which is running in the background and prevent your application from exiting.
You can run System.exit(0) at the end of your script to stop all the background threads.
Also have you considered using Akka scheduler instead of Java Timer?

Multiple Scala actors servicing one task

I need to process multiple data values in parallel ("SIMD"). I can use the java.util.concurrent APIs (Executors.newFixedThreadPool()) to process several values in parallels using Future instances:
import java.util.concurrent.{Executors, Callable}
class ExecutorsTest {
private class Process(value: Int)
extends Callable[Int] {
def call(): Int = {
// Do some time-consuming task
value
}
}
val executorService = {
val threads = Runtime.getRuntime.availableProcessors
Executors.newFixedThreadPool(threads)
}
val processes = for (process <- 1 to 1000) yield new Process(process)
val futures = executorService.invokeAll(processes)
// Wait for futures
}
How do I do the same thing using Actors? I do not believe that I want to "feed" all of the processes to a single actor because the actor will then execute them sequentially.
Do I need to create multiple "processor" actors with a "dispatcher" actor that sends an equal number of processes to each "processor" actor?
If you just want fire-and-forget processing, why not use Scala futures?
import scala.actors.Futures._
def example = {
val answers = (1 to 4).map(x => future {
Thread.sleep(x*1000)
println("Slept for "+x)
x
})
val t0 = System.nanoTime
awaitAll(1000000,answers: _*) // Number is timeout in ms
val t1 = System.nanoTime
printf("%.3f seconds elapsed\n",(t1-t0)*1e-9)
answers.map(_()).sum
}
scala> example
Slept for 1
Slept for 2
Slept for 3
Slept for 4
4.000 seconds elapsed
res1: Int = 10
Basically, all you do is put the code you want inside a future { } block, and it will immediately return a future; apply it to get the answer (it will block until done), or use awaitAll with a timeout to wait until everyone is done.
Update: As of 2.11, the way to do this is with scala.concurrent.Future. A translation of the above code is:
import scala.concurrent._
import duration._
import ExecutionContext.Implicits.global
def example = {
val answers = Future.sequence(
(1 to 4).map(x => Future {
Thread.sleep(x*1000)
println("Slept for "+x)
x
})
)
val t0 = System.nanoTime
val completed = Await.result(answers, Duration(1000, SECONDS))
val t1 = System.nanoTime
printf("%.3f seconds elapsed\n",(t1-t0)*1e-9)
completed.sum
}
If you can use Akka, take a look at the ActorPool support: http://doc.akka.io/routing-scala
It lets you specify parameters about how many actors you want running in parallel and then dispatches work to those actors.