2011-04-30 8 views
5

Hola Estoy usando scala (2.8.1) para implementar un controlador de tareas que consume tiempo usando el actor, sin embargo, no puedo limpiarlo cuando ejecuto mis pruebas unitarias, por lo que mis pruebas de unidad colgaron para siempre.cómo limpiar mi actor muerto en Scala

cómo me llamo el método es:

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

lo que planeo hacer es mantener la referencia de los actores y llame salida de cada sobre, el fragmento de código es la siguiente:

  • init, inicializa a los actores y conserva la referencia de cada actor.
  • destory, call exit en cada actor.
  • detener, salir de la llamada en este actor.

Sin embargo, parece que no funciona bien. cómo limpiar a todos los actores en este caso?

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 
    } 

Respuesta

3

1) En su caso concreto, me gustaría simplificar

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

sólo caller ! projectConfig.instantiate. Ya estás haciendo una llamada desde el subsistema del actor, por lo que no es necesario un ajuste adicional.

Además de eso, a pesar de que generalmente se recomienda llamar a los agentes de medio ambiente de los actores (desove de la llamada), que no es un 'debe' en absoluto (y no el mal va a pasar, si se llama el actor directamente en una env no actor). En su caso, envolver las llamadas en lugar de agregar problemas (repetitivo e inconsistencias).

2) Lo que está sucediendo realmente en actor ! exit es actor ! Actor.exit (assuming that you have a wildcard import on Actor). Este código arroja una excepción al intentar evaluar Actor.exit, y no se envía nada al actor. Para detener al actor, debe llamar al exit en su instancia. Se puede hacer a través de un mensaje de envío, que llamará a un protegido exit:

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