timeout - Scala how to use akka actors to handle a timing out operation efficiently -


i evaluating javascript scripts using rhino in restful service. wish there evaluation time out. have created mock example actor (using scala 2.10 akka actors).

case class evaluate(expression: string)  class rhinoactor extends actor {    override def prestart() = { println("start context'"); super.prestart()}    def receive = {     case evaluate(expression) ⇒ {       thread.sleep(100)       sender ! "complete"     }   }    override def poststop() = { println("stop context'"); super.poststop()} } 

now run use actor follows:

  def run {     val t = system.currenttimemillis()     val system = actorsystem("mysystem")      val actor = system.actorof(props[rhinoactor])      implicit val timeout = timeout(50 milliseconds)     val future = (actor ? evaluate("10 + 50")).mapto[string]      val result = try(await.result(future, duration.inf))      println(system.currenttimemillis() - t)     println(result)     actor ! poisonpill      system.shutdown()   } 

is wise use actorsystem in closure may have simultaneous requests on it?

should make actorsystem global, , ok in context?

is there more appropriate alternative approach?

edit: think need use futures directly, need prestart , poststop. investigating. edit: seems don't hooks futures.

i'll try , answer of questions you.

first, actorsystem heavy weight construct. should not create 1 per request needs actor. should create 1 globally , use single instance spawn actors (and won't need system.shutdown() anymore in run). believe covers first 2 questions.

your approach of using actor execute javascript here seems sound me. instead of spinning actor per request, might want pool bunch of rhinoactors behind router, each instance having it's own rhino engine setup during prestart. doing eliminate per request rhino initialization costs, speeding js evaluations. make sure size pool appropriately. also, won't need sending poisonpill messages per request if adopt approach.

you might want non-blocking callbacks oncomplete, onsuccess , onfailure opposed using blocking await. these callbacks respect timeouts , preferable blocking higher throughput. long whatever way way upstream waiting response can handle asynchronicity (i.e. async capable web request), suggest going route.

the last thing keep in mind though code return caller after timeout if actor has yet respond, actor still goes on processing message (performing evaluation). not stop , move onto next message because caller timed out. wanted make clear in case wasn't.

edit

in response comment stopping long execution there things related akka consider first. can call stop actor, send kill or posionpill, none of these stop if processing message it's processing. prevent receiving new messages. in case, rhino, if infinite script execution possibility, suggest handling within rhino itself. dig answers on post (stopping rhino engine in middle of execution) , setup rhino engine in actor in such way stop if has been executing long. failure kick out supervisor (if pooled) , cause pooled instance restarted init new rhino in prestart. might best approach dealing possibility of long running scripts.


Comments