I'm looking for a possibility to loop for certain duration.
For example, I'd like to println("Hi there!") for 5 minutes.
I'm using Scala and Akka.
I was thinking about using future, which will be finished in 5 minutes, meanwhile I would use while cycle on it with check that it's not completed. Such approach doesn't work for me, as my class isn't an actor, and I cant finish the future from outside the loop.
Any ideas or maybe there are ready solutions for such things?
Current ugly solution:
def now = Calendar.getInstance.getTime.getTime
val ms = durationInMins * 60 * 1000
val finish = now + ms
while (now <= finish) {
println("hi")
}
Thanks in advance!
The solution of #Radian is potentially dangerous, as it will eventually block all the threads in the ExecutorService, when your app runs this code several times concurrently. You can better use a Deadline for that:
import scala.concurrent.duration._
val deadline = 5.seconds.fromNow
while(deadline.hasTimeLeft) {
// ...
}
val timeout = future{Thread.sleep(5000)}
while(!timeout.isCompleted){println("Hello")}
This works, but I don't like it because:
Long loops without sleeps are bad.
Long loops in the main Thread is blocking your application
Another solution, would be to move your logic (the print function) into a separate Actor, and introduce a scheduler to handle the timing for you, and another scheduler-once to send a PoisonPill after a duration
More about Scheduler
You can also do it in the actor manner:
case object Init
case object Loop
case object Stop
class Looper extends Actor {
var needToRun = true
def receive = {
case Init =>
needToRun = true
self ! Loop
case Stop =>
needToRun = false
case Loop =>
if(needToRun) {
//do whatever you need to do
self ! Loop
}
}
}
And use scheduler to send a message:
looperRef ! Init
system.scheduler.scheduleOnce(5 MINUTES, looperRef, Stop)
Related
I want to execute a method every 5 seconds. I also need a start and stop
I am quite new to Scala so I don't have enough experience with timer object. I have played a bit with it but I do not have enough understanding of it
val timer = new Timer()
val run = timer.schedule(method(messageSender, "hello"), 5.Seconds)
def method (messageSender: MessageSender, message: String): Unit ={
messageSender.sendMessage(message)
}
run.start()
run.stop()
I know the code is not correct. I just wrote how I think it would look like raughly.
run.start would start executing the method every 5 seconds. and run.stop would stop the execution. Anyone have a rough idea of how I can achieve this.
By using akka actor I am doing it as follows
import system.dispatcher
val system = ActorSystem("mySystem", config)
//1 second as initial delay
system.scheduler.schedule(1 seconds, 5 seconds) {
taskToCall()
}
You can refer to this https://doc.akka.io/docs/akka/current/scheduler.html?language=scala
I create 10000 actors and send a message to each, but it seems that the akka system can't complete all the work.
when I check the thread state, they are all in TIMED_WATIING.
My code:
class Reciver extends Actor {
val log = Logging(context.system, this)
var num = 0
def receive = {
case a: Int => log.info(s"[${self.path}] receive $a, num is $num")
Thread.sleep(2000)
log.info(s"[${self.path}] processing $a, num is $num")
num = a
}
}
object ActorSyncOrAsync extends App {
val system = ActorSystem("mysys")
for (i <- 0 to 10000) {
val actor = system.actorOf(Props[Reciver])
actor ! i
}
println("main thread send request complete")
}
You should remove Thread.sleep or (if you're using default thread-pool) surround it with:
scala.concurrent.blocking {
Thread.sleep(2000)
}
scala.concurrent.blocking marks the computation to have a managed blocking, which means that it tells the pool that computation is not taking CPU resources but just waits for some result or timeout. You should be careful with this however. So, basically, this advice works if you're using Thread.sleep for debugging purposes or just to emulate some activity - no Thread.sleep (even surrounded by blocking) should take place in production code.
Explanation:
When some fixed pool is used (including fork-join as it doesn't steal work from threads blocked by Thread.sleep) - there is only POOL_SIZE threads (it equals to the number of cores in your system by default) is used for computation. Everything else is going to be queued.
So, let's say 4 cores, 2 seconds per task, 10000 tasks - it's gonna take 2*10000/4 = 5000 seconds.
The general advice is to not block (including Thread.sleep) inside your actors: Blocking needs careful management. If you need to delay some action it's better to use Scheduler (as #Lukasz mentioned): http://doc.akka.io/docs/akka/2.4.4/scala/scheduler.html
Akka's documentation warns:
When using future callbacks, such as onComplete, onSuccess, and onFailure, inside actors you need to carefully avoid closing over the containing actor’s reference, i.e. do not call methods or access mutable state on the enclosing actor from within the callback
It seems to me that if I could get the Future which wants to access the mutable state to run on the same dispatcher that arranges for mutual exclusion of threads handling actor messages then this issue could be avoided. Is that possible? (Why not?)
The ExecutionContext provided by context.dispatcher is not tied to the actor messages dispatcher, but what if it were? i.e.
class MyActorWithSafeFutures {
implicit def safeDispatcher = context.dispatcherOnMessageThread
var successCount = 0
var failureCount = 0
override def receive: Receive = {
case MakeExternalRequest(req) =>
val response: Future[Response] = someClient.makeRequest(req)
response.onComplete {
case Success(_) => successCount += 1
case Failure(_) => failureCount += 1
}
response pipeTo sender()
}
}
}
Is there any way to do that in Akka?
(I know that I could convert the above example to do something like self ! IncrementSuccess, but this question is about mutating actor state from Futures, rather than via messages.)
It looks like I might be able to implement this myself, using code like the following:
class MyActorWithSafeFutures {
implicit val executionContext: ExecutionContextExecutor = new ExecutionContextExecutor {
override def execute(runnable: Runnable): Unit = {
self ! runnable
}
override def reportFailure(cause: Throwable): Unit = {
throw new Error("Unhandled throwable", cause)
}
}
override def receive: Receive = {
case runnable: Runnable => runnable.run()
... other cases here
}
}
Would that work? Why doesn't Akka offer that - is there some huge drawback I'm not seeing?
(See https://github.com/jducoeur/Requester for a library which does just this in a limited way -- for Asks only, not for all Future callbacks.)
Your actor is executing its receive under one of the dispatcher's threads, and you want to spin off a Future that's firmly attached to this particular thread? In that case the system can't reuse this thread to run a different actor, because that would mean the thread was unavailable when you wanted to execute the Future. If it happened to use that same thread to execute someClient, you might deadlock with yourself. So this thread can no longer be used freely to run other actors - it has to belong to MySafeActor.
And no other threads can be allowed to freely run MySafeActor - if they were, two different threads might try to update successCount at the same time and you'd lose data (e.g. if the value is 0 and two threads both try to do successCount +=1, the value can end up as 1 rather that 2). So to do this safely, MySafeActor has to have a single Thread that's used for itself and its Future. So you end up with MySafeActor and that Future being tightly, but invisibly, coupled. The two can't run at the same time and could deadlock against each other. (It's still possible for a badly-written actor to deadlock against itself, but the fact that all the code using that actor's "imaginary mutex" is in a single place makes it easier to see potential problems).
You could use traditional multithreading techniques - mutexes and the like - to allow the Future and MySafeActor to run concurrently. But what you really want is to encapsulate successCount in something that can be used concurrently but safely - some kind of... Actor?
TL;DR: either the Future and the Actor: 1) may not run concurrently, in which case you may deadlock 2) may run concurrently, in which case you will corrupt data 3) access state in a concurrency-safe way, in which case you're reimplementing Actors.
You could use a PinnedDispatcher for your MyActorWithSafeFutures actor class which would create a thread pool with exactly one thread for each instance of the given class, and use context.dispatcher as execution context for your Future.
To do this you have to put something like this in your application.conf:
akka {
...
}
my-pinned-dispatcher {
executor = "thread-pool-executor"
type = PinnedDispatcher
}
and to create your actor:
actorSystem.actorOf(
Props(
classOf[MyActorWithSafeFutures]
).withDispatcher("my-pinned-dispatcher"),
"myActorWithSafeFutures"
)
Although what you are trying to achieve breaks completely the purpose of the actor model. The actor state should be encapsulated, and actor state changes should be driven by incoming messages.
This does not answer your question directly, but rather offers an alternative solution using Akka Agents:
class MyActorWithSafeFutures extends Actor {
var successCount = Agent(0)
var failureCount = Agent(0)
def doSomethingWithPossiblyStaleCounts() = {
val (s, f) = (successCount.get(), failureCount.get())
statisticsCollector ! Ratio(f/s+f)
}
def doSomethingWithCurrentCounts() = {
val (successF, failureF) = (successCount.future(), failureCount.future())
val ratio : Future[Ratio] = for {
s <- successF
f <- failureF
} yield Ratio(f/s+f)
ratio pipeTo statisticsCollector
}
override def receive: Receive = {
case MakeExternalRequest(req) =>
val response: Future[Response] = someClient.makeRequest(req)
response.onComplete {
case Success(_) => successCount.send(_ + 1)
case Failure(_) => failureCount.send(_ + 1)
}
response pipeTo sender()
}
}
The catch is that if you want to operate on the counts that would result if you were using #volatile, then you need to operate inside a Future, see doSomethingWithCurrentCounts().
If you are fine with having values which are eventually consistent (there might be pending updates scheduled for the Agents), then something like doSometinghWithPossiblyStaleCounts() is fine.
#rkuhn explains why this would be a bad idea on the akka-user list:
My main consideration here is that such a dispatcher would make it very convenient to have multiple concurrent entry points into the Actor’s behavior, where with the current recommendation there is only one—the active behavior. While classical data races are excluded by the synchronization afforded by the proposed ExecutionContext, it would still allow higher-level races by suspending a logical thread and not controlling the intermediate execution of other messages. In a nutshell, I don’t think this would make the Actor easier to reason about, quite the opposite.
I'm trying to get started with akka in scala. In the main scala thread I'd like to start an akka actor, send one message to it, and block until that actor terminates. What is the best way to do this?
For example I have a test actor that just repeatedly sends messages to itself:
class Incrementer() extends Actor {
val maxMessages = 5
var counter = 0
def receive() = {
case DoIncr() => {
if (counter < maxMessages) {
counter += 1
self ! DoIncr()
} else {
self.stop()
}
}
}
}
and it is invoked via:
val inc = actorOf(new Incrementer()).start()
val result = inc !! DoIncr()
println(result) // this should block this thread, but it doesn't seem to.
// do other stuff
That block takes just over 5,000 ms to execute instead of what I expect to be a few ms, so it seems to have to do with a default future timeout - and the program does not actually terminate. All I'm really trying to do is time the performance of sending x number of messages. What's going on here?
As Viktor mentioned, in order for !! to terminate successfully, you have to reply to the message. The 5 second delay you are seeing the actor's default timeout, which is configurable. More info can be found on the Akka site.
If you use forward to send the message instead of !, then self.reply will respond to the original sender.
The first message you send to an Akka actor performs some setup that doesn't happen when processing other messages. Be sure to take that into account for your timings.
Corrected code would be:
import akka.actor._
object DoIncr
class Incrementer extends Actor {
val maxMessages = 5
var counter = 0
def receive = {
case DoIncr =>
if (counter < maxMessages) {
counter += 1
self forward DoIncr
} else {
self.reply(()) // replying with () since we have nothing better to say
self.stop()
}
}
}
Aside: I made a few other changes to get your code in line with idiomatic Scala. Your code works without these changes, but it now looks like more typical Scala code.
Case classes without parameter lists have been deprecated. Use objects instead.
If you have a class without a parameter list, you can omit the parenthesis
Actor's receive method does not have parens; your implementing class shouldn't have them either.
It's purely a matter of style, but the body of a case statement does not require braces.
What's the best way to have an actor sleep? I have actors set up as agents which want to maintain different parts of a database (including getting data from external sources). For a number of reasons (including not overloading the database or communications and general load issues), I want the actors to sleep between each operation. I'm looking at something like 10 actor objects.
The actors will run pretty much infinitely, as there will always be new data coming in, or sitting in a table waiting to be propagated to other parts of the database etc. The idea is for the database to be as complete as possible at any point in time.
I could do this with an infinite loop, and a sleep at the end of each loop, but according to http://www.scala-lang.org/node/242 actors use a thread pool which is expanded whenever all threads are blocked. So I imagine a Thread.sleep in each actor would be a bad idea as would waste threads unnecessarily.
I could perhaps have a central actor with its own loop that sends messages to subscribers on a clock (like async event clock observers)?
Has anyone done anything similar or have any suggestions? Sorry for extra (perhaps superfluous) information.
Cheers
Joe
There was a good point to Erlang in the first answer, but it seems disappeared. You can do the same Erlang-like trick with Scala actors easily. E.g. let's create a scheduler that does not use threads:
import actors.{Actor,TIMEOUT}
def scheduler(time: Long)(f: => Unit) = {
def fixedRateLoop {
Actor.reactWithin(time) {
case TIMEOUT => f; fixedRateLoop
case 'stop =>
}
}
Actor.actor(fixedRateLoop)
}
And let's test it (I did it right in Scala REPL) using a test client actor:
case class Ping(t: Long)
import Actor._
val test = actor { loop {
receiveWithin(3000) {
case Ping(t) => println(t/1000)
case TIMEOUT => println("TIMEOUT")
case 'stop => exit
}
} }
Run the scheduler:
import compat.Platform.currentTime
val sched = scheduler(2000) { test ! Ping(currentTime) }
and you will see something like this
scala> 1249383399
1249383401
1249383403
1249383405
1249383407
which means our scheduler sends a message every 2 seconds as expected. Let's stop the scheduler:
sched ! 'stop
the test client will begin to report timeouts:
scala> TIMEOUT
TIMEOUT
TIMEOUT
stop it as well:
test ! 'stop
There's no need to explicitly cause an actor to sleep: using loop and react for each actor means that the underlying thread pool will have waiting threads whilst there are no messages for the actors to process.
In the case that you want to schedule events for your actors to process, this is pretty easy using a single-threaded scheduler from the java.util.concurrent utilities:
object Scheduler {
import java.util.concurrent.Executors
import scala.compat.Platform
import java.util.concurrent.TimeUnit
private lazy val sched = Executors.newSingleThreadScheduledExecutor();
def schedule(f: => Unit, time: Long) {
sched.schedule(new Runnable {
def run = f
}, time , TimeUnit.MILLISECONDS);
}
}
You could extend this to take periodic tasks and it might be used thus:
val execTime = //...
Scheduler.schedule( { Actor.actor { target ! message }; () }, execTime)
Your target actor will then simply need to implement an appropriate react loop to process the given message. There is no need for you to have any actor sleep.
ActorPing (Apache License) from lift-util has schedule and scheduleAtFixedRate Source: ActorPing.scala
From scaladoc:
The ActorPing object schedules an actor to be ping-ed with a given message at specific intervals. The schedule methods return a ScheduledFuture object which can be cancelled if necessary
There unfortunately are two errors in the answer of oxbow_lakes.
One is a simple declaration mistake (long time vs time: Long), but the second is some more subtle.
oxbow_lakes declares run as
def run = actors.Scheduler.execute(f)
This however leads to messages disappearing from time to time. That is: they are scheduled but get never send. Declaring run as
def run = f
fixed it for me. It's done the exact way in the ActorPing of lift-util.
The whole scheduler code becomes:
object Scheduler {
private lazy val sched = Executors.newSingleThreadedScheduledExecutor();
def schedule(f: => Unit, time: Long) {
sched.schedule(new Runnable {
def run = f
}, time - Platform.currentTime, TimeUnit.MILLISECONDS);
}
}
I tried to edit oxbow_lakes post, but could not save it (broken?), not do I have rights to comment, yet. Therefore a new post.