Sto sviluppando un'applicazione che utilizza Akka e una cosa che mi infastidisce per tutto il tempo che riguarda la dichiarazione dei messaggi con lo Actor
. Dove dovrei dichiarare i messaggi? Nell'oggetto companion receiver o nell'oggetto companion del mittente o in qualche terzo posto?Dove dovrebbero essere dichiarati i messaggi degli attori?
risposta
squadra L'Akka raccomanda messaggio deve essere definito nello stesso luogo il metodo props
dovrebbe essere: in the Receiver's Companion object perché il ricevitore implementa la funzione parziale receive
e ha bisogno di conoscere tutti i messaggi che supporta. Inoltre, più mittenti possono inviare una serie di messaggi (implementati dal Destinatario), quindi non è possibile inserirli in un singolo mittente.
Se the official Typesafe Activator template activator-akka-scala-seed è di qualche importanza per quanto riguarda le buone pratiche di Akka i messaggi dovrebbero essere parte di oggetto associato, come mostrato nella PingActor
attore seguente (copiato direttamente dal modello):
package com.example
import akka.actor.{Actor, ActorLogging, Props}
class PingActor extends Actor with ActorLogging {
import PingActor._
var counter = 0
val pongActor = context.actorOf(PongActor.props, "pongActor")
def receive = {
case Initialize =>
log.info("In PingActor - starting ping-pong")
pongActor ! PingMessage("ping")
case PongActor.PongMessage(text) =>
log.info("In PingActor - received message: {}", text)
counter += 1
if (counter == 3) context.system.shutdown()
else sender() ! PingMessage("ping")
}
}
object PingActor {
val props = Props[PingActor]
case object Initialize
case class PingMessage(text: String)
}
Nota PingActor
che contiene tutte le messaggi accettati dall'attore (come avrete notato che non è seguito rigorosamente dal momento che anche PongActor.PongMessage
è accettato, ma non definito nell'oggetto associato PingActor
).
Da un'altra domanda How to restrict actor messages to specific types?ilViktor said:
La pratica comune è quella di dichiarare quali messaggi attore può ricevere nell'oggetto compagna dell'attore, che lo rende molto più facile sapere cosa può ricevere.
In realtà questo esempio mostra che i tipi di messaggio possono essere (ri) usati tra diversi attori. Forse è una buona pratica mettere i messaggi _command_ nell'oggetto complementare dell'attore ricevente e dei messaggi _event_ altrove? Qui il 'PingMessage' dovrebbe ** non ** essere nell'oggetto compagno' PingActor', perché questo attore non riceve questo messaggio. Il posto giusto è l'oggetto compagno del 'PongActor'. Il 'PongMessage' dovrebbe essere nell'oggetto compagno' PingActor' ricevente. Ma è event-ish e potrebbe essere definito in un oggetto neutro ed emesso anche da altri attori. – Sebastian
@Sebastian suona un po 'troppo complicato per i miei gusti. Se qualcuno ti chiede "dove" non saresti in grado di rispondere subito - usiamo semplici regole qui "nel compagno" è facile da ricordare, e ha senso in quanto è "il ragazzo che li capisce", pensaci come questo "è quel ragazzo * protocollo *". –
@ Konrad'ktoso'Malawski Mi piacciono 3 cose nel tuo commento: 1. convenzioni, 2. protocolli e 3. trattare oggetti/attori come esseri viventi _talking_ l'uno con l'altro. Ma la domanda iniziale era: _Dove dovrei dichiarare i messaggi? Nell'oggetto companion receiver o nell'oggetto companion del mittente?_ Scusate se sono troppo severo, ma nell'esempio precedente non è ovvio in quale oggetto companion debbano essere dichiarati 'PingMessage' e' PongMessage'. Il 'PongActor' ricevente dovrebbe convenzionalmente comprendere il' PingMessage' nel suo _protocol_, non è vero? ;-) – Sebastian
- 1. Dove dovrebbero essere creati virtualenvs?
- 2. I messaggi di eccezione indirizzati allo sviluppatore dovrebbero essere localizzati?
- 3. Dove dovrebbero essere piazzati i test unitari in Meteor?
- 4. Dove dovrebbero essere collocati i sovraccarichi dell'operatore non membro?
- 5. I contesti dei dati dovrebbero essere statici?
- 6. Dove dovrebbero essere inserite le eccezioni utilizzate da più progetti?
- 7. Dove dovrebbero essere attive le query del database?
- 8. Dove dovrebbero essere posizionate le funzioni "globali" di Symfony?
- 9. I commenti Pascal dovrebbero essere nidificati?
- 10. Dove dovrebbero essere fatti gli oggetti in una pagina ASP.NET?
- 11. Elenco degli errori di SQL Server che dovrebbero essere riprovati?
- 12. Quando potrebbero i Futures essere più appropriati degli attori (o viceversa) in Scala?
- 13. I percorsi in Express possono essere dichiarati con un loop?
- 14. Perché i sindacati anonimi globali devono essere dichiarati come statici?
- 15. Identificazione degli attori per casi d'uso
- 16. Dove nello stack di chiamata dovrebbero essere eseguiti i controlli di ruolo?
- 17. Dove sono memorizzati i messaggi flash?
- 18. I pattern "statici" non dovrebbero essere sempre statici?
- 19. Gli attori di Scala possono elaborare più messaggi contemporaneamente?
- 20. Dove dovrebbero andare le dichiarazioni 'CreateMap'?
- 21. Come prevenire la fame degli attori in presenza di altri attori di lunga durata?
- 22. Dovrebbero essere usati i metodi parseJSON/getJSON di jQuery?
- 23. Perché i vararg dovrebbero essere l'ultimo nella firma del metodo?
- 24. I file .class dovrebbero essere messi sotto controllo di versione?
- 25. CA1034: I tipi annidati non dovrebbero essere visibili
- 26. I documenti dovrebbero essere scritti dai programmatori esperti?
- 27. I meta tag dovrebbero essere codificati in HTML?
- 28. quali dovrebbero essere i valori di GOPATH e GOROOT?
- 29. Scala, attori, cosa succede ai messaggi in arrivo non letti?
- 30. Le implementazioni IDisposable.Dispose() dovrebbero essere idempotenti?
Potresti ampliare * * Il team di Akka consiglia "*? Una pagina web sarebbe appropriata. –
Noi consigliamo questo :-) Aggiunto un link ai documenti per la risposta di Soumya => http://doc.akka.io/docs/akka/2.3.8/scala/actors.html#recommended-practices –
Grazie Konrad! –