Reputation: 2168
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!
Upvotes: 7
Views: 3626
Reputation: 1342
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)
Upvotes: 0
Reputation: 7596
val timeout = future{Thread.sleep(5000)}
while(!timeout.isCompleted){println("Hello")}
This works, but I don't like it because:
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
Upvotes: 0
Reputation: 24423
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) {
// ...
}
Upvotes: 23