开发者

how to cleanup my dead actor in Scala

开发者 https://www.devze.com 2023-03-01 12:01 出处:网络
Hi I am using scala(2.8.1) to implement a time-consuming task handler using actor, however, I am not able to clean it up when running my unit tests, so my unit tests hung forever.

Hi I am using scala(2.8.1) to implement a time-consuming task handler using actor, however, I am not able to clean it up when running my unit tests, so my unit tests hung forever.

how I call the method is:

  val configs = new ProjectsConfig("XXXXXXXXXXXXX")
  try {
    configs.start
    configs.init//time consuming stuff
  } finally {
    configs.destory
    configs.stop
  }

What I plan to do is to keep the actors' reference and call exit on each on, the code snippet is like this:

  • init, initialize the actors and keep the reference of each actor.
  • destory, call exit on each actor.
  • stop, call exit on 开发者_运维技巧this actor.

however, it seems not working well. how to clean all actors in this case?

class ProjectsConfig(val url: String) extends Actor {
  private var actors: List[Actor] = List()
  private object Stop

  def init = {
    val caller = this;
    for (projectConfig <- list) {
      val myActor: Actor = actor {
        caller ! projectConfig.instantiate
      }
      actors = actors ::: List(myActor)
    }
  }

  def act() {
    while (true) {
      receive {
        case project: Project =>
          Projects.update(project)
        case Stop => exit()
      }
    }
  }

  def destory {
    for (actor <- actors) {
      try {
        actor ! exit
      } catch {
        case e => System.out.println(e.printStackTrace)
      }
    }
  }

  def stop() {
    this ! Stop
  }


1) In your specific case, I would simplify

val myActor: Actor = actor {
caller ! projectConfig.instantiate
}

to just caller ! projectConfig.instantiate. You're already making a call from the actor's sub-system, so an additional wrapping is not needed.

Besides that, though it's generally recommended to call actors from the actors' environment (spawning the call), it's not a "must" at all (and no evil will happen, if you call the actor directly in a non-actor env). In your case, wrapping the calls rather adds problems (boilerplate and inconsistencies).

2) What's actually happening in actor ! exit is actor ! Actor.exit (assuming that you have a wildcard import on Actor). This code throws an exception attempting to evaluate Actor.exit, and nothing is sent to the actor. In order to stop the actor, you must call exit on its instance. It can be done through a message-sending, that will call a protected exit:

actor{
  loop{
     react{
        case `exit => exit('stop)
     }
  }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消