2009-10-10 12 views
48

Me siento un poco inseguro sobre el uso de actores en Scala. He leído documentación sobre cómo hacer las cosas, pero creo que también necesitaría algunas reglas NO HACER para poder usarlas. Creo que me temo que los usaré de manera incorrecta, y ni siquiera lo notaré.Scala actors - peores prácticas?

¿Puedes pensar en algo que, si se aplica, daría como resultado la ruptura de los beneficios que traen los actores de Scala, o incluso resultados erróneos?

Respuesta

52
  • Evitar !? siempre que sea posible. Usted obtener un sistema bloqueado!

  • Envíe siempre un mensaje desde un subproceso Actor-hilo. Si esto significa la creación de un Actor transitoria a través del método Actor.actor que así sea:

    case ButtonClicked(src) => Actor.actor { controller ! SaveTrade(trdFld.text) }

  • Añadir una "cualquier otro mensaje" manejador a las reacciones de su agente. De lo contrario es imposible averiguar si va a enviar un mensaje al actor equivocado:

    case other => log.warning(this + " has received unexpected message " + other

  • No utilice Actor.actor para sus actores principales, sublcass Actor lugar. La razón de esto es que es solo por subclases que puede proporcionar un método sensible toString. Una vez más, la depuración de los actores es muy difícil si los registros están llenos de declaraciones como:

    12:03 [INFO] Sending RequestTrades(2009-10-12) to scala.actors.Actor$anonfun$1

  • documento los actores en el sistema, indicando explícitamente qué mensajes van a recibir y precisa cómo deben calcular la respuesta. El uso de actores da como resultado la conversión de un procedimiento estándar (normalmente encapsulado dentro de un método) para que se convierta en una lógica dispersa en las reacciones de múltiples actores. Es fácil perderse sin una buena documentación.

  • Siempre asegúrese de que puede comunicarse con su actor fuera de su react bucle para encontrar su estado.Por ejemplo, siempre declaro que se invoca un método a través de un MBean que se parece al siguiente fragmento de código. De lo contrario, puede ser muy difícil saber si su actor se está ejecutando, se ha apagado, tiene una gran cola de mensajes, etc.

.

def reportState = { 
    val _this = this 
    synchronized { 
    val msg = "%s Received request to report state with %d items in mailbox".format(
        _this, mailboxSize) 
    log.info(msg) 
    } 
    Actor.actor { _this ! ReportState } 
} 
  • enlace a tus actores juntos y utilice trapExit = true - de lo contrario pueden fallar en silencio que significa que su programa no está haciendo lo que usted piensa que es y probablemente salir de la memoria como los mensajes permanecen en el buzón del actor.

  • creo que algunas otras opciones interesantes alrededor de marca que se tomen decisiones utilizando actores se han destacado y herehere

+0

Todo lo demás tiene sentido de inmediato, pero tengo curiosidad acerca de su segundo punto de siempre enviar mensajes desde dentro de un hilo Actor. ¿Cuál es la motivación principal aquí, rendimiento/claridad/algo más? No lo sigo del todo. – Michael

+0

¡Veo que has sufrido mucho escribiendo el código Actor en Scala! :-) –

+2

* @ Michael *: si no declaras explícitamente un Actor, se creará uno para ti y se vinculará al 'Thread' como' ThreadLocal'. No estoy del todo claro para mí que este enfoque sea lógicamente seguro o esté libre de fugas de memoria. Mucho más simple para declarar explícitamente uno –

12

Sé que esto realmente no responde a la pregunta, pero al menos debería alegrarse por el hecho de que la concurrencia basada en mensajes es mucho menos propensa a errores extraños que la concurrencia basada en subprocesos de memoria compartida.

supongo que usted ha visto las directrices actor en Programación en Scala, pero para el registro:

  • actores no deben bloquear al procesar un mensaje. En caso de que quiera bloquear, intente organizar un mensaje más tarde.
  • Use react {} en lugar de receive {} cuando sea posible.
  • Comuníquese con los actores solo a través de mensajes.
  • Prefieren los mensajes inmutables.
  • Haga que los mensajes sean independientes.
+0

Hola, Gracias por su respuesta rápida - que hace que puntos muy útiles. Estaba pensando que también "compartir estado" es algo que no se debe hacer ... pero no sé exactamente lo que esto significa en el nivel de código - quizás, - teniendo como mensaje una clase C con un campo privado F y con un captador clásico para este campo (getF) - de un actor, enviando una instancia de C - del actor actor, recibiendo C y llamando a getF ? ¿Esto podría significar 'estado compartido'? ¡Gracias! – teo

+0

El estado compartido es estado al que se accede por más de un hilo. No es tan malo como el estado mutable compartido, pero requiere un razonamiento sobre la coherencia a menos que se comparta solo después de la construcción y en lo sucesivo inmutable. Por lo tanto, enviar una referencia a ti mismo en un mensaje no sería el movimiento más inteligente, aunque una referencia a un objeto mutable es peor que una referencia a un mensaje inmutable. – DigitalRoss

Cuestiones relacionadas