agentes Scala como filas individuais roscados
-
05-07-2019 - |
Pergunta
Eu gostaria de usar atores em um programa onde eu vou ter algum tipo de restrição em torno de tratar alguns dos atores como se fossem filas. Por exemplo, suponha que eu tenho algum sistema externo para que os eventos de alteração são aplicadas e também alguns de cache de dados do sistema externo. Então, eu tenho 2 atores:
-
ChangeApplicationActor
-
CacheActor
Como parte do ChangeApplicationActor
, quando eu aplicar uma alteração a alguns X
entidade no sistema externo, Quero enviar um evento para contar a CacheActor
a sincronização:
val changeApplicationActor = actor {
loop {
react {
case ChangeInstruction(x) =>
externalSystem.applyChange(x)
cacheActor ! Sync(x)
}
}
}
Mas agora tenho dois requisitos:
- O
CacheActor
tem estado interno e, idealmente, eu gostaria que para processar suas instruçõesSync
sequencialmente - Se eu acabar com caixa de entrada do
CacheActor
contendo duas instruçõesSync(x)
para o mesmo valor dex
, então eu gostaria de ignorar o segundo (ou seja, eu só deve ter uma pendente instruçãoSync
para qualquer valor dado dex
)
Existe alguma maneira de forçar um ator para ser single-threaded? Existe alguma maneira eu posso acessar a caixa postal do ator e remover quaisquer eventos duplicados? Eu não posso evitar a implementação do CacheActor
como, um, não um ator ?
Solução
Um ator é garantido para executar somente em um segmento de cada vez, e as mensagens na caixa de correio do ator estão em ordem FIFO, então # 1 está lá.
2 é mais complicado porque não há nenhum suporte nativo para ele. Há um atributo sobre o ator chamado de "caixa de correio". Você pode acessar a caixa de correio diretamente em vez de através de receber ou reagir. Tudo que você tem a fazer é chamar puxar a correspondência de mensagens de sincronização de saída da caixa de correio antes de terminar o processamento da mensagem. Ao fazer isso, você deve sincronizar sobre o ator, a fim de manter o outro segmento de tentar as coisas adicionar à caixa de correio durante um envio de mensagem.
Deve-se notar que a sincronização no ator elimina as garantias impasse liberdade feitos pela biblioteca, e irá reduzir a escalabilidade. Mas de um ponto de vista prático, você provavelmente estará ok.