Les acteurs de la Scala en file d'attente à un seul thread
-
05-07-2019 - |
Question
J'aimerais utiliser des acteurs dans un programme dans lequel une certaine sorte de restriction empêchera de traiter certains acteurs comme des files d'attente. Par exemple, supposons que je dispose d'un système externe auquel les événements de modification sont appliqués ainsi que d'une mémoire cache des données du système externe. J'ai donc 2 acteurs:
-
ChangeApplicationActor
-
CacheActor
Dans le cadre de ChangeApplicationActor
, lorsque j'applique une modification à une entité X
du système externe, je souhaite envoyer un événement pour indiquer à CacheActor.
à synchroniser:
val changeApplicationActor = actor {
loop {
react {
case ChangeInstruction(x) =>
externalSystem.applyChange(x)
cacheActor ! Sync(x)
}
}
}
Mais j'ai maintenant deux exigences:
- Le
CacheActor
a un état interne et, idéalement, j'aimerais qu'il traite ses instructionsSync
de manière séquentielle - Si je me retrouve avec la boîte de réception de
CacheActor
contenant deux instructionsSync (x)
pour la même valeur dex
, alors je 'souhaite ignorer le second (c’est-à-dire que je ne devrais avoir qu’une instructionSync
en attente pour une valeur donnée dex
)
Existe-t-il un moyen de forcer un acteur à utiliser un seul thread? Est-il possible d'accéder à la boîte aux lettres de l'acteur et de supprimer les doublons? Ne puis-je pas éviter d'implémenter CacheActor
car, euh, pas un acteur ?
La solution
Il est garanti qu'un acteur ne s'exécute que sur un seul thread à la fois, et les messages de sa boîte aux lettres sont dans l'ordre FIFO, donc # 1 y est.
2 est plus délicat car il n’existe pas de support intégré. Il existe un attribut sur l'acteur appelé "boîte aux lettres". Vous pouvez accéder à la boîte aux lettres directement au lieu de recevoir ou de réagir. Avant de traiter le message, il vous suffit d'extraire l'appel des messages Sync correspondants de la boîte aux lettres. Pour ce faire, vous devez effectuer une synchronisation sur l'acteur afin d'empêcher un autre thread de tenter d'ajouter des éléments à la boîte aux lettres pendant l'envoi d'un message.
Il convient de noter que la synchronisation sur l'acteur élimine les garanties de liberté de blocage établies par la bibliothèque et réduira l'évolutivité. Mais d’un point de vue pratique, tout ira bien pour vous.