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).  
Requisitos
- .NET 8+
- Pacotes NuGet:
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;
    }
}
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;
    }
}
Assinatura de um Evento
Para inscrever um ator em um evento:
- Crie o ator usando o sistema de atores.
- 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); // 
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 EventStreamtambé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).  
 


 
    
Top comments (0)