Created
February 23, 2026 20:16
-
-
Save alexandrebl/86332033e91984d68bdeaeccea2725fa to your computer and use it in GitHub Desktop.
AkkaPipelineAndManualResetEvent.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ======================================================================================================== | |
| // SISTEMA DE PROCESSAMENTO DE PEDIDOS COM AKKA.NET - PIPELINE DE ATORES ENCADEADOS | |
| // ======================================================================================================== | |
| // | |
| // Este projeto demonstra o uso de ATORES ENCADEADOS (Actor Pipeline) usando o framework Akka.NET. | |
| // O objetivo é processar pedidos através de múltiplas etapas, onde cada ator é responsável por | |
| // uma única responsabilidade (Single Responsibility Principle). | |
| // | |
| // -------------------------------------------------------------------------------------------------------- | |
| // O QUE É AKKA.NET? | |
| // -------------------------------------------------------------------------------------------------------- | |
| // Akka.NET é um framework para construir sistemas concorrentes, distribuídos e resilientes usando | |
| // o modelo de ATORES. Cada ator é uma unidade isolada de processamento que: | |
| // - Possui seu próprio estado privado | |
| // - Processa mensagens de forma assíncrona e sequencial | |
| // - Comunica-se com outros atores apenas através de mensagens | |
| // - Não compartilha memória (evita problemas de concorrência) | |
| // | |
| // -------------------------------------------------------------------------------------------------------- | |
| // ARQUITETURA DO PIPELINE DE PROCESSAMENTO | |
| // -------------------------------------------------------------------------------------------------------- | |
| // | |
| // O sistema implementa um PIPELINE DE 5 ATORES ENCADEADOS que processam pedidos em etapas: | |
| // | |
| // ┌─────────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ | |
| // │ OrderReceiver │ ───> │ Validation │ ───> │ Payment │ ───> │ Shipping │ ───> │ Notification │ | |
| // │ Actor │ │ Actor │ │ Actor │ │ Actor │ │ Actor │ | |
| // └─────────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────────┘ | |
| // Etapa 1 Etapa 2 Etapa 3 Etapa 4 Etapa 5 | |
| // | |
| // -------------------------------------------------------------------------------------------------------- | |
| // FLUXO DETALHADO DE PROCESSAMENTO | |
| // -------------------------------------------------------------------------------------------------------- | |
| // | |
| // 1. ORDERRECEIVER ACTOR (Recepção) | |
| // - Recebe: Order (pedido original) | |
| // - Função: Ponto de entrada do sistema, recebe pedidos dos clientes | |
| // - Processa: Registra o recebimento do pedido | |
| // - Envia para: ValidationActor | |
| // | |
| // 2. VALIDATION ACTOR (Validação) | |
| // - Recebe: Order | |
| // - Função: Valida os dados do pedido (quantidade > 0 e preço > 0) | |
| // - Processa: Verifica integridade dos dados | |
| // - Envia para: PaymentActor (se válido) ou interrompe o fluxo (se inválido) | |
| // - Mensagem enviada: ValidatedOrder | |
| // | |
| // 3. PAYMENT ACTOR (Pagamento) | |
| // - Recebe: ValidatedOrder | |
| // - Função: Processa o pagamento do pedido | |
| // - Processa: Calcula o valor total, simula aprovação do pagamento, gera ID de transação | |
| // - Envia para: ShippingActor | |
| // - Mensagem enviada: PaidOrder (inclui TransactionId) | |
| // | |
| // 4. SHIPPING ACTOR (Envio) | |
| // - Recebe: PaidOrder | |
| // - Função: Prepara e despacha o pedido | |
| // - Processa: Simula preparação do envio, gera código de rastreamento | |
| // - Envia para: NotificationActor | |
| // - Mensagem enviada: ShippedOrder (inclui TrackingNumber) | |
| // | |
| // 5. NOTIFICATION ACTOR (Notificação) | |
| // - Recebe: ShippedOrder | |
| // - Função: Envia notificação final ao cliente | |
| // - Processa: Gera notificação com todos os detalhes do pedido concluído | |
| // - Final do pipeline: Não envia para outros atores | |
| // | |
| // -------------------------------------------------------------------------------------------------------- | |
| // TIPOS DE MENSAGENS NO PIPELINE | |
| // -------------------------------------------------------------------------------------------------------- | |
| // | |
| // As mensagens são objetos imutáveis que transportam dados entre atores: | |
| // | |
| // Order → Pedido original (Id, Product, Quantity, Price) | |
| // ValidatedOrder → Pedido validado (Order + IsValid) | |
| // PaidOrder → Pedido pago (Order + TransactionId) | |
| // ShippedOrder → Pedido enviado (Order + TrackingNumber) | |
| // CompletedOrder → Pedido concluído (Order + Status) [definida mas não usada neste exemplo] | |
| // | |
| // -------------------------------------------------------------------------------------------------------- | |
| // VANTAGENS DESTA ARQUITETURA | |
| // -------------------------------------------------------------------------------------------------------- | |
| // | |
| // 1. DESACOPLAMENTO: Cada ator conhece apenas o próximo ator na cadeia | |
| // 2. ESCALABILIDADE: Pode-se adicionar múltiplas instâncias de cada ator para processar em paralelo | |
| // 3. RESILIÊNCIA: Se um ator falha, o sistema pode reiniciá-lo sem afetar os outros | |
| // 4. MANUTENIBILIDADE: Cada ator tem uma responsabilidade clara e bem definida | |
| // 5. TESTABILIDADE: Cada ator pode ser testado isoladamente | |
| // 6. ASSÍNCRONO: Processamento não-bloqueante, cada ator processa em seu próprio ritmo | |
| // | |
| // -------------------------------------------------------------------------------------------------------- | |
| // CONCEITOS IMPORTANTES DO AKKA.NET UTILIZADOS | |
| // -------------------------------------------------------------------------------------------------------- | |
| // | |
| // - ActorSystem: Container que gerencia todos os atores | |
| // - ActorOf: Cria uma nova instância de ator | |
| // - Props.Create: Factory para criar atores com parâmetros de construtor | |
| // - IActorRef: Referência para enviar mensagens a um ator (não acessa o ator diretamente) | |
| // - Tell(): Envia mensagem assíncrona (fire-and-forget) | |
| // - Receive<T>: Define um handler para processar mensagens do tipo T | |
| // - ReceiveActor: Classe base para atores que usam pattern matching de mensagens | |
| // | |
| // -------------------------------------------------------------------------------------------------------- | |
| using Akka.Actor; | |
| var mre = new ManualResetEvent(false); | |
| var actorSystem = ActorSystem.Create("MyActorSystem"); | |
| // Criar atores encadeados para processar pedidos | |
| var notificationActor = actorSystem.ActorOf<NotificationActor>("notification"); | |
| var shippingActor = actorSystem.ActorOf(Props.Create(() => new ShippingActor(notificationActor)), "shipping"); | |
| var paymentActor = actorSystem.ActorOf(Props.Create(() => new PaymentActor(shippingActor)), "payment"); | |
| var validationActor = actorSystem.ActorOf(Props.Create(() => new ValidationActor(paymentActor)), "validation"); | |
| var orderReceiver = actorSystem.ActorOf(Props.Create(() => new OrderReceiverActor(validationActor)), "orderReceiver"); | |
| // Enviar pedidos para processar | |
| orderReceiver.Tell(new Order { Id = 1, Product = "Notebook", Quantity = 1, Price = 3500.00m }); | |
| orderReceiver.Tell(new Order { Id = 2, Product = "Mouse", Quantity = 2, Price = 50.00m }); | |
| orderReceiver.Tell(new Order { Id = 3, Product = "Teclado", Quantity = 1, Price = 250.00m }); | |
| Console.WriteLine("Aguardando processamento dos pedidos...\n"); | |
| int count = 0; | |
| Timer timer = new(callback => | |
| { | |
| count++; | |
| Console.WriteLine($"\nTimer tick: {count}"); | |
| if (count == 5) | |
| { | |
| mre.Set(); | |
| Console.WriteLine($"Timer alcançou {count} ticks, encerrando..."); | |
| } | |
| }); | |
| timer.Change(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(2)); | |
| mre.WaitOne(); | |
| Console.WriteLine("\nEncerrando o sistema de atores..."); | |
| await actorSystem.Terminate(); | |
| // Mensagens | |
| public class Order | |
| { | |
| public int Id { get; set; } | |
| public string Product { get; set; } = string.Empty; | |
| public int Quantity { get; set; } | |
| public decimal Price { get; set; } | |
| } | |
| public class ValidatedOrder | |
| { | |
| public Order Order { get; set; } = null!; | |
| public bool IsValid { get; set; } | |
| } | |
| public class PaidOrder | |
| { | |
| public Order Order { get; set; } = null!; | |
| public string TransactionId { get; set; } = string.Empty; | |
| } | |
| public class ShippedOrder | |
| { | |
| public Order Order { get; set; } = null!; | |
| public string TrackingNumber { get; set; } = string.Empty; | |
| } | |
| public class CompletedOrder | |
| { | |
| public Order Order { get; set; } = null!; | |
| public string Status { get; set; } = string.Empty; | |
| } | |
| // Ator 1: Recebe o pedido inicial | |
| public class OrderReceiverActor : ReceiveActor | |
| { | |
| private readonly IActorRef _validationActor; | |
| public OrderReceiverActor(IActorRef validationActor) | |
| { | |
| _validationActor = validationActor; | |
| Receive<Order>(order => | |
| { | |
| Console.WriteLine($"[OrderReceiver] Pedido #{order.Id} recebido: {order.Product} x{order.Quantity}"); | |
| _validationActor.Tell(order); | |
| }); | |
| } | |
| } | |
| // Ator 2: Valida o pedido | |
| public class ValidationActor : ReceiveActor | |
| { | |
| private readonly IActorRef _paymentActor; | |
| public ValidationActor(IActorRef paymentActor) | |
| { | |
| _paymentActor = paymentActor; | |
| Receive<Order>(order => | |
| { | |
| Console.WriteLine($"[Validation] Validando pedido #{order.Id}..."); | |
| bool isValid = order.Quantity > 0 && order.Price > 0; | |
| if (isValid) | |
| { | |
| Console.WriteLine($"[Validation] Pedido #{order.Id} validado com sucesso!"); | |
| _paymentActor.Tell(new ValidatedOrder { Order = order, IsValid = true }); | |
| } | |
| else | |
| { | |
| Console.WriteLine($"[Validation] Pedido #{order.Id} inválido!"); | |
| } | |
| }); | |
| } | |
| } | |
| // Ator 3: Processa o pagamento | |
| public class PaymentActor : ReceiveActor | |
| { | |
| private readonly IActorRef _shippingActor; | |
| public PaymentActor(IActorRef shippingActor) | |
| { | |
| _shippingActor = shippingActor; | |
| Receive<ValidatedOrder>(validatedOrder => | |
| { | |
| if (validatedOrder.IsValid) | |
| { | |
| var order = validatedOrder.Order; | |
| Console.WriteLine($"[Payment] Processando pagamento de R$ {order.Price * order.Quantity:F2} para pedido #{order.Id}..."); | |
| string transactionId = Guid.NewGuid().ToString()[..8]; | |
| Console.WriteLine($"[Payment] Pagamento aprovado! Transaction ID: {transactionId}"); | |
| _shippingActor.Tell(new PaidOrder { Order = order, TransactionId = transactionId }); | |
| } | |
| }); | |
| } | |
| } | |
| // Ator 4: Processa o envio | |
| public class ShippingActor : ReceiveActor | |
| { | |
| private readonly IActorRef _notificationActor; | |
| public ShippingActor(IActorRef notificationActor) | |
| { | |
| _notificationActor = notificationActor; | |
| Receive<PaidOrder>(paidOrder => | |
| { | |
| var order = paidOrder.Order; | |
| Console.WriteLine($"[Shipping] Preparando envio do pedido #{order.Id}..."); | |
| string trackingNumber = $"BR{Random.Shared.Next(10000000, 99999999)}"; | |
| Console.WriteLine($"[Shipping] Pedido #{order.Id} despachado! Código de rastreio: {trackingNumber}"); | |
| _notificationActor.Tell(new ShippedOrder | |
| { | |
| Order = order, | |
| TrackingNumber = trackingNumber | |
| }); | |
| }); | |
| } | |
| } | |
| // Ator 5: Envia notificação final | |
| public class NotificationActor : ReceiveActor | |
| { | |
| public NotificationActor() | |
| { | |
| Receive<ShippedOrder>(shippedOrder => | |
| { | |
| var order = shippedOrder.Order; | |
| Console.WriteLine($"[Notification] Enviando notificação para pedido #{order.Id}..."); | |
| Console.WriteLine($"[Notification] ✓ Pedido #{order.Id} concluído com sucesso!"); | |
| Console.WriteLine($"[Notification] Produto: {order.Product}"); | |
| Console.WriteLine($"[Notification] Rastreio: {shippedOrder.TrackingNumber}"); | |
| }); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment