DEV Community

Rafael Andrade
Rafael Andrade

Posted on

EventStream no Proto.Actor Explicado: Comunicação Publicação-Assinatura Entre Atores

Introdução

O Proto.Actor oferece uma funcionalidade poderosa chamada EventStream, que atua como um despachante de publicação/assinatura multicanal. Este artigo explora como usar esse mecanismo para implementar comunicação orientada a eventos entre atores.

Fluxo de Eventos (EventStream)

O EventStream permite um padrão de publicação/assinatura (pub/sub) no Proto.Actor, possibilitando que atores (identificados por seus IDs de Processo, ou PID) se inscrevam em tipos específicos de eventos. Ele também é um componente crítico para gerenciar eventos de infraestrutura, como mensagens não entregues (ex.: tratamento de DeadLetter).

pub/sub

Requisitos

Atores

Para este exemplo, implementamos dois atores para demonstrar interação orientada a eventos.

OrderActor

O OrderActor cria pedidos e publica um evento OrderCreated via EventStream:

public class OrderActor : IActor
{
    private readonly List<Order> _orders = [];
    public Task ReceiveAsync(IContext context)
    {
        if (context.Message is CreateOrder createOrder)
        {
            var order = new Order(createOrder.Id, createOrder.Amount);
            _orders.Add(order);
            context.Respond(order);
            // Publica evento no EventStream
            context.System.EventStream.Publish(new OrderCreated(order)); // 
        }
        else if (context.Message is AllOrder)
        {
            context.Respond(_orders.ToList());
        }
        return Task.CompletedTask;
    }
}
Enter fullscreen mode Exit fullscreen mode

PaymentActor

O PaymentActor se inscreve em eventos OrderCreated e mantém uma lista de pedidos aguardando pagamento:

public class PaymentActor : IActor
{
    private List<Order> _waitingForPayment = [];
    public Task ReceiveAsync(IContext context)
    {
        if (context.Message is OrderCreated orderCreated)
        {
            _waitingForPayment.Add(orderCreated.Order); // Reage ao evento
        }
        else if (context.Message is OrderPaid orderPaid)
        {
            _waitingForPayment.RemoveAll(x => x.Id == orderPaid.Id);
        }
        else if (context.Message is IsWaitingForPayment isWaitingForPayment)
        {
            context.Respond(_waitingForPayment.Any(x => x.Id == isWaitingForPayment.Id));
        }
        return Task.CompletedTask;
    }
}
Enter fullscreen mode Exit fullscreen mode

Assinatura de um Evento

Para inscrever um ator em um evento:

  1. Crie o ator usando o sistema de atores.
  2. Use EventStream.Subscribe<T>() para registrar o ator para um tipo específico de evento:
// Criando atores
var actorOrder = system.Root.Spawn(Props.FromProducer(() => new OrderActor()));
var actorPayment = system.Root.Spawn(Props.FromProducer(() => new PaymentActor()));

// Inscrevendo-se em eventos OrderCreated
system.EventStream.Subscribe<OrderCreated>(system.Root, actorPayment); // 
Enter fullscreen mode Exit fullscreen mode

Conceitos Chave

  • Ciclo de Vida do EventStream: Eventos são publicados para todos os assinantes, e as assinaturas persistem até serem explicitamente canceladas.
  • Tratamento de Mensagens não Entregues (DeadLetter): O EventStream também enfileira mensagens não entregues (ex.: ao enviar para um ator encerrado).

Conclusão

O EventStream do Proto.Actor simplifica arquiteturas orientadas a eventos, desacoplando atores por meio de um mecanismo robusto de pub/sub. Esse padrão é ideal para cenários como origem de eventos (event sourcing), monitoramento ou preocupações transversais (ex.: registro de logs).

Referências

EventStream | Proto.Actor

Código de exemplo no Github

Top comments (0)