Actores Scala-¿peores prácticas?
akka (2)
Sé que esto realmente no responde a la pregunta, pero al menos debe tener en cuenta el hecho de que la concurrencia basada en mensajes es mucho menos propensa a errores extraños que la concurrencia basada en hilos de memoria compartida.
Supongo que has visto las pautas del actor en Programación en Scala , pero para el registro:
- Los actores no deben bloquear mientras procesan un mensaje. Cuando desee bloquear, intente arreglar para obtener un mensaje más tarde.
- Use
react {}
lugar dereceive {}
cuando sea posible. - Comunicarse con los actores solo a través de mensajes.
- Prefiere mensajes inmutables.
- Hacer mensajes autocontenidos.
Me siento un poco inseguro sobre el uso de actores en Scala. He leído documentación sobre cómo hacer cosas, pero creo que también necesitaría algunas reglas de "NO HACER" para sentirme libre de usarlas. Creo que me temo que los usaré de manera incorrecta, y ni siquiera lo notaré.
¿Se le ocurre algo que, si se aplica, resultaría en una ruptura de los beneficios que traen los actores de Scala, o incluso resultados erróneos?
¿Evitar
!?
donde sea posible. Obtendrá un sistema bloqueado!Envíe siempre un mensaje desde un subproceso del subsistema Actor. Si esto significa crear un Actor transitorio a través del método
Actor.actor
, que así sea:case ButtonClicked(src) => Actor.actor { controller ! SaveTrade(trdFld.text) }
Agregue un controlador de "cualquier otro mensaje" a las reacciones de su actor. De lo contrario, es imposible averiguar si está enviando un mensaje al actor incorrecto:
case other => log.warning(this + " has received unexpected message " + other
No uses
Actor.actor
para tus actores primarios, en su lugar, mejora elActor
. La razón de esto es que solo mediante la subclasificación puede proporcionar un métodotoString
sensible. Nuevamente, la depuración de actores es muy difícil si sus registros están llenos de declaraciones como:12:03 [INFO] Sending RequestTrades(2009-10-12) to scala.actors.Actor$anonfun$1
Documente a los actores en su sistema, indicando explícitamente qué mensajes recibirán y precisamente 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 convertirse en una propagación lógica a través de las reacciones de múltiples actores. Es fácil perderse sin una buena documentación.
Siempre asegúrese de poder comunicarse con su actor fuera de su ciclo de
react
para encontrar su estado. Por ejemplo, siempre declaro que se invoca un método a través de unMBean
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 cerrado, 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 }
}
Vincule a sus actores y use
trapExit = true
; de lo contrario, pueden fallar en silencio, lo que significa que su programa no está haciendo lo que cree que es y probablemente se quedará sin memoria a medida que los mensajes permanecen en el buzón del actor.Creo que here y here se han destacado algunas otras opciones interesantes sobre decisiones de diseño que deben tomarse utilizando actores.