Attori alla Scala come code a thread singolo
-
05-07-2019 - |
Domanda
Mi piacerebbe usare gli attori in un programma in cui avrò una sorta di restrizione nel trattare alcuni attori come se fossero code. Ad esempio, supponiamo che io abbia un sistema esterno a cui vengono applicati gli eventi di modifica e anche una cache dei dati del sistema esterno. Quindi ho 2 attori:
-
ChangeApplicationActor
-
CacheActor
Come parte del ChangeApplicationActor
, quando applico una modifica a qualche entità X
nel sistema esterno, voglio inviare un evento per dire al CacheActor
da sincronizzare:
val changeApplicationActor = actor {
loop {
react {
case ChangeInstruction(x) =>
externalSystem.applyChange(x)
cacheActor ! Sync(x)
}
}
}
Ma ora ho due requisiti:
- Il
CacheActor
ha uno stato interno e idealmente mi piacerebbe che elaborasse le sue istruzioniSync
in sequenza - Se finisco con la posta in arrivo
CacheActor
contenente due istruzioniSync (x)
per lo stesso valore dix
, allora I vorrei ignorare il secondo (cioè dovrei avere solo un'istruzioneSync
in sospeso per un dato valore dix
)
Esiste un modo per costringere un attore a un thread singolo? È possibile accedere alla cassetta postale dell'attore e rimuovere eventuali eventi duplicati? Non posso evitare di implementare CacheActor
come, um, non un attore ?
Soluzione
Un attore è garantito per essere eseguito su un solo thread alla volta e i messaggi nella cassetta postale dell'attore sono in ordine FIFO, quindi il numero 1 è lì.
2 è più complicato in quanto non è supportato. C'è un attributo sull'attore chiamato " mailbox. & Quot; È possibile accedere direttamente alla cassetta postale anziché tramite ricezione o reazione. Tutto quello che devi fare è estrarre dalla casella di posta i messaggi di sincronizzazione corrispondenti prima di completare l'elaborazione del messaggio. Nel fare ciò, è necessario sincronizzarsi sull'attore per evitare che un altro thread tenti di aggiungere elementi alla cassetta postale durante l'invio di un messaggio.
Va ??notato che la sincronizzazione sull'attore elimina le garanzie di libertà di deadlock rese dalla libreria e ridurrà la scalabilità. Ma da un punto di vista pratico probabilmente starai bene.