Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sleeping actors?

Tags:

scala

actor

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

like image 553
Joe Avatar asked Aug 03 '09 20:08

Joe


People also ask

Who is a famous person with insomnia?

Lady Gaga and Madonna are often compared to one another and both have admitted battling insomnia. George Clooney has also freely admitted to dealing with insomnia. During an interview with the Hollywood Reporter the actor admitted that he wakes multiple times a night and loathes going to bed without the TV on.

Do celebrities get a lot of sleep?

Being successful often means compromises, and many successful celebrities admit that they do not sleep much. While some claim to not need more than a few hours a night, others forego essential rest to juggle work and a social life.

Where do actors sleep?

When filming takes place on location, the ideal method to accommodate actors is to stay in hotels. They travel there, do their daily roles, and then return to their lodgings to rest and sleep.

Do people with insomnia sleep?

People with insomnia can't fall asleep, stay asleep or get enough restful slumber. Insomnia is a common sleep disorder. Over time, lack of sleep can lead to health problems like diabetes, hypertension and weight gain. Behavioral and lifestyle changes can improve your rest.


2 Answers

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
like image 174
Alexander Azarov Avatar answered Sep 19 '22 05:09

Alexander Azarov


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.

like image 29
oxbow_lakes Avatar answered Sep 20 '22 05:09

oxbow_lakes