Akka.net actor can't handle low latency messages?

171 Views Asked by At

I have this work-flow:

  1. A method inside parent

            Receive<UpdatePositionCmd>(cmd =>
        {                
            cmd.Qty = 150;
            cmd.Price = 100;
            _positionCoordinatorActor.Tell(cmd);
    
            Thread.Sleep(30);
    
            cmd.Qty = 250;
            cmd.Price = 200;
            _positionCoordinatorActor.Tell(cmd);
    
            Thread.Sleep(30);
    
            cmd.Qty = 133;
            cmd.Price = 300;
            _positionCoordinatorActor.Tell(cmd);
        });
    
  2. Method inside the position Coordinator which receives messages from #1, finds appropriate child and forwards the message:

            Command<UpdatePositionCmd>(cmd =>
        {
            var child = LookupChild(cmd.PositionName);
            if (child != ActorRefs.Nobody)
            {
                child.Tell(cmd);
            }
            else
            {
                var @event = new PositionUpdatedEvent(cmd);
    
                Persist(@event, positionUpdatedEvent =>
                {
                    var childActor = Context.ActorOf(Props.Create(() => new PositionActor()), cmd.PositionName);
                    childActor.Tell(cmd);
                });
            }
        });
    
  3. Method inside a child which gets the forwarded message:

            Command<UpdatePositionCmd>(cmd =>
        {
            Console.Write($"\nCmd Qty: {cmd.Qty}");
            Qty += cmd.Qty;
        });
    

So my question: with the Thread.Sleep(30) between "Tells" I get correct output:

Cmd Qty: 150
Cmd Qty: 250
Cmd Qty: 133
Total Qty: 533

But should I remove or decrease the Thread.Sleep(30) I am getting this messed up results where basically it only reads the last message but three times:

Cmd Qty: 133
Cmd Qty: 133
Cmd Qty: 133
Total Qty: 399

Please help. Thank you!

1

There are 1 best solutions below

0
On BEST ANSWER

A method inside parent receives an UpdatePositionCmd instance, passes it on to the coordinator, and then updates this very same command. With the delay this is less obvious because the command is issued the second time after processing of the first has completed.

You should create a new instance for each call to _positionCoordinatorActor.Tell and make the UpdatePositionCmd immutable so you don't inadvertently change an instance that's sent away already.