Partilhar via


Grãos replicados

Às vezes, pode haver várias instâncias do mesmo grão ativo, como ao operar um cluster múltiplo e usar o OneInstancePerClusterAttribute. O JournaledGrain foi projetado para oferecer suporte a instâncias replicadas com o mínimo de atrito. Ele depende de provedores de consistência de log para executar os protocolos necessários para garantir que todas as instâncias concordem com a mesma sequência de eventos. Em particular, cuida dos seguintes aspetos:

  • Versões consistentes: Todas as versões do estado de grão (exceto as versões provisórias) são baseadas na mesma sequência global de eventos. Em particular, se duas instâncias virem o mesmo número de versão, elas verão o mesmo estado.

  • Eventos de corrida: várias instâncias podem gerar um evento simultaneamente. O provedor de consistência resolve essa corrida e garante que todos concordem na mesma sequência.

  • Notificações/Reatividade: Depois que um evento é gerado em uma instância de grão, o provedor de consistência não apenas atualiza o armazenamento, mas também notifica todas as outras instâncias de grão.

Para uma discussão geral sobre a consistência, consulte o nosso TechReport e o documento GSP (Global Sequence Protocol).

Eventos condicionais

Os eventos de corrida podem ser problemáticos se tiverem um conflito, ou seja, não devem ambos cometer por algum motivo. Por exemplo, ao retirar dinheiro de uma conta bancária, duas instâncias podem determinar independentemente que há fundos suficientes para uma retirada e emitir um evento de retirada. Mas a combinação de ambos os eventos pode exagerar. Para evitar isso, a JournaledGrain API suporta um RaiseConditionalEvent método.

bool success = await RaiseConditionalEvent(
    new WithdrawalEvent() { /* ... */ });

Eventos condicionais Verifique se a versão local corresponde à versão no armazenamento. Se não, significa que a sequência de eventos cresceu entretanto, o que significa que este evento perdeu uma corrida contra algum outro evento. Nesse caso, o evento condicional não é anexado ao log e RaiseConditionalEvent retorna false.

Este é o análogo do uso de e-tags com atualizações de armazenamento condicional e, da mesma forma, fornece um mecanismo simples para evitar cometer eventos conflitantes.

É possível e sensato usar eventos condicionais e incondicionais para o mesmo grão, como a DepositEvent e a WithdrawalEvent. Os depósitos não precisam ser condicionais: mesmo que uma DepositEvent corrida perca uma corrida, ela não precisa ser cancelada, mas ainda pode ser anexada à sequência global do evento.

Aguardando a tarefa retornada é RaiseConditionalEvent suficiente para confirmar o evento, ou seja, não é necessário também chamar ConfirmEvents.

Sincronização explícita

Às vezes, é desejável garantir que um grão seja totalmente alcançado com a versão mais recente. Isso pode ser feito ligando para:

await RefreshNow();

Isto faz duas coisas:

  1. Confirma todos os acontecimentos não confirmados.
  2. Ele carrega a versão mais recente do armazenamento.