2009-08-21 16 views
6

Ahora he escrito algunas aplicaciones con actores scala y estoy interesado en cómo la gente se ha acercado o ha tratado algunos de los problemas que he encontrado.Escribo aplicaciones con actores de Scala en la práctica

¡Una plétora de clases de mensajes o!?

Tengo un actor que reacciona a una operación de usuario y debe causar que algo suceda. Digamos que react s a un mensaje UserRequestsX(id). Un problema continuo que tengo es que, como quiero modularizar mis programas, un solo actor por sí solo no puede completar la acción sin involucrar a otros actores. Por ejemplo, supongamos que necesito usar el parámetro id para recuperar un grupo de valores y luego estos deben ser eliminados a través de otro actor. Si estuviera escribiendo un programa Java normal, podría hacer algo como:

public void reportTrades(Date date) { 
    Set<Trade> trades = persistence.lookup(date); 
    reportService.report(trades); 
} 

Que es lo suficientemente simple. Sin embargo, usar actores esto se vuelve un poco molesto porque quiero evitar el uso de !?. Un actor reacciona al mensaje ReportTrades(date), pero debe solicitar un PersistenceActor para las transacciones y luego un ReportActor para informarlas. La única forma que he encontrado para hacer esto es hacer:

react { 
    case ReportTrades(date) => 
     persistenceActor ! GetTradesAndReport(date) 
} 

Así que en mi PersistenceActor tengo un bloque de reaccionar:

react { 
    case GetTradesAndReport(date) => 
     val ts = trades.get(date) //from persietent store 
     reportActor ! ReportTrades(ts) 
} 

Pero ahora tengo 2 problemas:

  1. Tengo que crear clases de mensajes adicionales para representar la misma solicitud (es decir, "transacciones de informe"). De hecho, tengo tres en este escenario, pero puedo tener muchos más: se convierte en un problema mantener el seguimiento de estos
  2. ¿Cómo debo llamar al primer y tercer mensaje ReportTrades? Es confuso llamarlos a ambos ReportTrades (o si lo hago, debo ponerlos en paquetes separados). Esencialmente no hay tal cosa como overloading una clase por tipo val.

¿Hay algo que me falta? ¿Puedo evitar esto? ¿Debería renunciar y usar !? ¿La gente usa alguna estructura organizacional para aclarar lo que está pasando?

+0

¿Es seguro acceder directamente a la tienda persistente en "reaccionar"? Pensé que no podrías hacer operaciones de bloqueo.Tal vez "recibir" es necesario para ese actor en particular. –

Respuesta

2

Para mí, su mensaje ReportTrades está mezclando dos conceptos diferentes. Una es una Solicitud, la orden es una Respuesta. Pueden llamarse GetTradesReport(Date) y SendTradesReport(List[Trade]), por ejemplo. O, tal vez, ReportTradesByDate(Date) y GenerateTradesReport(List[Trade]).

+0

Pero mi punto sigue en pie; Tengo todas estas clases utilizadas para nada más que pasar datos. Ayer escribí un código por el cual necesitaba "decorar" una solicitud con información de 4 actores separados. Incluso permitiendo nombres sensatos, ¡hay muchas clases confusas! –

+0

Bueno, tales clases nunca se usan solo para transmitir información. Se utilizan para transmitir información de un lugar a otro con un propósito. Si los nombra en consecuencia, mejora la legibilidad general del código. –

0

¿Hay algunas objeciones al uso de reply? O pasando trades alrededor? Si no es así, su código, probablemente se vería como

react { 
    case ReportTrades(date) => persistenceActor ! GetTrades(date) 
    case Trades(ts) => // do smth with trades 
} 

y

react { 
    case GetTrades(date) => reply(Trades(trades.get(date))) 
} 

respectivamente.

+0

Supongo que mi punto es que no puedo simplemente pasarle un objeto 'Trades' a mi coordinador como * ¿cómo sabría qué comando original se estaba invocando? * Por ejemplo, puedo tener varias cosas que debo hacer: * DeleteTrades *, * ReportTrades *, * LoadTrades * etc. El coordinador necesitará una respuesta como 'SomeTradesToReport',' SomeTradesToDelete' o 'SomeTradesToLoad' (asumiendo que estoy evitando'!? ') –

Cuestiones relacionadas