Example #1
0
        public void Should_properly_handle_the_response()
        {
            var     response = new FutureChannel <Purchased>();
            decimal price    = 0.0m;

            AnonymousActor.New(inbox =>
            {
                Auction.Request(new Ask(Id), inbox)
                .Within(30.Seconds())
                .Receive <Response <Status> >(m => status =>
                {
                    price = status.Body.CurrentBid;
                    Auction.Request(new Buy(status.Body.Token, 1), inbox)
                    .Within(30.Seconds())
                    .Receive <Response <Purchased> >(pm => pmsg => response.Complete(pmsg.Body))
                    .Otherwise(() => {});
                })
                .Receive <Response <Ended> >(m => ended => {});
            });

            response.WaitUntilCompleted(4.Seconds()).ShouldBeTrue("Timeout waiting for response");

            response.Value.AuctionId.ShouldEqual(Id);
            response.Value.Quantity.ShouldEqual(1);
            response.Value.Price.ShouldEqual(price);
        }
Example #2
0
        public void A_loopback_registry()
        {
            Address   = new Uri("loopback://localhost/");
            ReceivedA = new Future <A>();

            Registry = ActorRegistryFactory.New(x =>
            {
                x.Remote(r =>
                {
                    r.ListenTo(Address);
                });
            });

            ActorId = Guid.NewGuid();
            Actor   = AnonymousActor.New(inbox =>
            {
                inbox.Loop(loop =>
                {
                    loop.Receive <Message <A> >(message =>
                    {
                        ReceivedA.Complete(message.Body);

                        loop.Continue();
                    });
                });
            });

            Registry.Register(ActorId, Actor);
        }
Example #3
0
        public void Newly_created_account_should_have_correct_balence_and_credit()
        {
            ActorRef      account = ActorFactory.Create(inbox => new AccountActor(inbox, 100.0m)).GetActor();
            Future <bool> result  = new Future <bool>();

            decimal balance         = 0xDEADBEEF;
            decimal availableCredit = 0xDEADBEEF;
            decimal creditLimit     = 0xDEADBEEF;

            AnonymousActor.New(inbox =>
            {
                account.Request(new QueryAccountBalance(), inbox)
                .Receive <AccountBalance>(message =>
                {
                    balance         = message.Balance;
                    availableCredit = message.AvailableCredit;
                    creditLimit     = message.CreditLimit;

                    Console.WriteLine("Balance={0}, Credit={1}, Limit={2}",
                                      balance, availableCredit, creditLimit);
                    result.Complete(true);
                });
            });

            result.WaitUntilCompleted(5.Seconds());
            Assert.True(balance == 0 && availableCredit == 100.0m && creditLimit == 100.0m);
        }
Example #4
0
        public void Should_properly_serialize_a_response()
        {
            var actor = AnonymousActor.New(inbox =>
            {
                _channel.Respond(new Test
                {
                    Name = "Magic"
                }, "21");
            });

            ThreadUtil.Sleep(1.Seconds());
        }
Example #5
0
        public void An_exit_is_sent_to_an_actor()
        {
            _receivedA = new Future <A>();

            _actor = AnonymousActor.New(inbox =>
            {
                inbox.Receive <A>(message =>
                {
                    _receivedA.Complete(message);
                });
            });
        }
Example #6
0
        public void Should_prevent_the_actor_from_exiting()
        {
            AnonymousActor.New(inbox =>
            {
                _actor.Request <Exit>(inbox)
                .Within(5.Seconds())
                .Receive <Response <Exit> >(x => { });
            });
            _intercepted.WaitUntilCompleted(5.Seconds()).ShouldBeTrue("Exit was not intercepted");

            _actor.Send(new A());
            _receivedA.WaitUntilCompleted(5.Seconds()).ShouldBeTrue("A was not handled, did actor exit?");
        }
Example #7
0
        public void Should_support_the_repeat_syntax()
        {
            var completed = new Future <Status>();

            ActorRef auction = AnonymousActor.New(inbox =>
            {
                decimal currentBid = 0.0m;

                inbox.Loop(loop =>
                {
                    loop.Receive <Request <Bid> >(request =>
                    {
                        if (request.Body.MaximumBid > currentBid)
                        {
                            currentBid = request.Body.MaximumBid;
                        }

                        request.Respond(new StatusImpl
                        {
                            CurrentBid = currentBid
                        });

                        loop.Continue();
                    })
                    .Receive <Request <Ask> >(request =>
                    {
                        request.Respond(new StatusImpl
                        {
                            CurrentBid = currentBid
                        });

                        loop.Continue();
                    });
                });
            });

            ActorRef bidder = AnonymousActor.New(inbox =>
            {
                auction.Request(new BidImpl(13.5m), inbox)
                .Receive <Response <Status> >(bidResponse =>
                {
                    auction.Request <Ask>(inbox)
                    .Receive <Response <Status> >(askResponse => completed.Complete(askResponse.Body));
                });
            });

            completed.WaitUntilCompleted(5.Seconds()).ShouldBeTrue();

            bidder.Exit();
            auction.Exit();
        }
Example #8
0
        public void Should_not_receive_a_response_to_a_stupid_message()
        {
            var response = new FutureChannel <bool>();

            AnonymousActor.New(inbox =>
            {
                Auction.Request(new Ask(new Guid()), inbox)
                .Within(1.Seconds())
                .Receive <Response <Status> >(m => status => {})
                .Otherwise(() => response.Complete(true));
            });

            response.WaitUntilCompleted(4.Seconds()).ShouldBeTrue("Timeout waiting for otherwise to be called");
        }
Example #9
0
        public void A_stream_of_messages_is_received()
        {
            ActorFactory <Agent> agentFactory = ActorFactory.Create(inbox => new Agent(inbox));

            ActorRef agent = agentFactory.GetActor();

            for (int i = 0; i < _count; i++)
            {
                agent.Send(new Add
                {
                    Value = i
                });

                if (i == 100)
                {
                    agent.Send <Suspend>();
                }

                if (i == 500)
                {
                    agent.Send <Resume>();
                }
            }

            _response = new Future <Status>();
            var actor = AnonymousActor.New(inbox =>
            {
                Action loop = null;
                loop        = () =>
                {
                    agent.Request(new Status(), inbox)
                    .Receive <Response <Status> >(response =>
                    {
                        if (response.Body.Count == _count)
                        {
                            _response.Complete(response.Body);
                        }
                        else
                        {
                            loop();
                        }
                    });
                };

                loop();
            });

            _response.WaitUntilCompleted(8.Seconds());
        }
Example #10
0
        public void Should_receive_the_expected_value()
        {
            var response = new FutureChannel <Status>();

            AnonymousActor.New(inbox =>
            {
                Auction.Request(new Ask(Id), inbox)
                .Within(30.Seconds())
                .Receive <Response <Status> >(m => status => response.Complete(status.Body))
                .Receive <Response <Ended> >(m => ended => {});
            });

            response.WaitUntilCompleted(4.Seconds()).ShouldBeTrue("Timeout waiting for response");

            response.Value.AuctionId.ShouldEqual(Id);
        }
Example #11
0
        public void Easy_syntax_love()
        {
            ActorFactory <QuoteService> factory =
                StateMachineActorFactory.Create <QuoteServiceWorkflow, QuoteService>(inbox => new QuoteService(inbox), x =>
            {
                x.AccessCurrentState(s => s.CurrentState);

                x.Initially()
                .When(e => e.GetQuoteRequest)
                .Then(i => i.SendQuoteRequest)
                .TransitionTo(s => s.WaitingForResponse);

                x.During(s => s.WaitingForResponse)
                .When(e => e.CancelRequest)
                .Then(i => i.Cancel)
                .Finalize();
            });

            ActorRef service = factory.GetActor();


            var response = new Future <Response <RequestSent> >();

            var actor = AnonymousActor.New(inbox =>
            {
                service.Request(new GetQuote
                {
                    Symbol = "MSFT"
                }, inbox)
                .Receive <Response <RequestSent> >(r =>
                {
                    service.Request(new GetQuote
                    {
                        Symbol = "AAPL"
                    }, inbox)
                    .Receive <Response <RequestSent> >(rr =>
                    {
                        response.Complete(r);
                    });
                });
            });

            response.WaitUntilCompleted(5.Seconds()).ShouldBeTrue();

            service.Exit();
        }
Example #12
0
        public void Should_receive_the_alternate_ending_if_it_is_such()
        {
            Auction.Send(new End());

            var response = new FutureChannel <Ended>();

            AnonymousActor.New(inbox =>
            {
                Auction.Request(new Ask(Id), inbox)
                .Within(30.Seconds())
                .Receive <Response <Status> >(m => status => {})
                .Receive <Response <Ended> >(m => ended => response.Complete(ended.Body));
            });

            response.WaitUntilCompleted(4.Seconds()).ShouldBeTrue("Timeout waiting for response");

            response.Value.AuctionId.ShouldEqual(Id);
        }
Example #13
0
        public void Should_receive_a_fault_message()
        {
            var received = new Future <Fault>();

            AnonymousActor.New(inbox =>
            {
                inbox.Receive <Fault>(fault =>
                {
                    received.Complete(fault);
                });

                throw new NotImplementedException("A");
            });

            received.WaitUntilCompleted(5.Seconds()).ShouldBeTrue();
            received.Value.Message.ShouldEqual("A");

            Trace.WriteLine(received.Value.StackTrace);
        }
Example #14
0
        public void An_exit_is_sent_to_an_actor_that_intercepts_exit()
        {
            _intercepted = new Future <Exit>();
            _receivedA   = new Future <A>();

            _actor = AnonymousActor.New(inbox =>
            {
                inbox.Receive <Request <Exit> >(request =>
                {
                    _intercepted.Complete(request.Body);
                    request.Respond(request.Body);
                });

                inbox.Receive <A>(message =>
                {
                    _receivedA.Complete(message);
                });
            });
        }
Example #15
0
        public void When_two_actors_are_linked()
        {
            _a = AnonymousActor.New(inbox =>
            {
                inbox.Receive <Die>(x =>
                {
                    inbox.Exit();
                });
            });

            _b = AnonymousActor.New(inbox =>
            {
                _a.Link(inbox);

                inbox.Receive <Die>(x =>
                {
                });
            });
        }
Example #16
0
            public void Send(ConnectionContext context)
            {
                AnonymousActor.New(inbox =>
                {
                    _serviceCoordinator.Send <Request <ServiceStatus> >(new RequestImpl <ServiceStatus>(inbox, new ServiceStatus()));

                    inbox.Receive <Response <ServiceStatus> >(response =>
                    {
                        var view = new DashboardView(response.Body.Services);

                        context.Response.RenderSparkView(view, "dashboard.html");
                        context.Complete();
                    }, 30.Seconds(), () =>
                    {
                        context.Response.StatusCode = (int)HttpStatusCode.RequestTimeout;
                        context.Complete();
                    });
                });
            }
Example #17
0
        public void Something()
        {
            ActorRef actor = AnonymousActor.New(inbox =>
            {
                inbox.Loop(loop =>
                {
                    loop.Receive <Request <Add> >(message =>
                    {
                        int result = message.Body.Left + message.Body.Right;

                        Trace.WriteLine("Responding with " + result + " on thread "
                                        + Thread.CurrentThread.ManagedThreadId);

                        message.Respond(new AddResult
                        {
                            Result = result
                        });

                        loop.Continue();
                    });


                    loop.Receive <Exit>(msg =>
                    {
                        inbox.Exit();
                        loop.Continue();
                    });
                });
            });

            var future = new Future <AddResult>();

            AnonymousActor.New(inbox =>
                               actor.Request(new Add
            {
                Left  = 56,
                Right = 23
            }, inbox)
                               .Receive <AddResult>(response => future.Complete(response)));

            future.WaitUntilCompleted(8.Seconds()).ShouldBeTrue("Didn't responsd");
        }
Example #18
0
        public void Should_not_call_the_other_receive_handlers()
        {
            var statusResponse = new FutureChannel <Status>();
            var endedResponse  = new FutureChannel <Ended>();

            AnonymousActor.New(inbox =>
            {
                Auction.Request(new Ask(Id), inbox)
                .Within(10.Seconds())
                .Receive <Response <Status> >(m => status =>
                {
                    statusResponse.Complete(status.Body);
                    Auction.Send(new End());
                    Auction.Request(new Ask(Id), inbox);
                })
                .Receive <Response <Ended> >(m => ended => endedResponse.Complete(ended.Body));
            });

            statusResponse.WaitUntilCompleted(4.Seconds()).ShouldBeTrue("Timeout waiting for response");
            endedResponse.WaitUntilCompleted(2.Seconds()).ShouldBeFalse("The receiver for Ended should not have been called.");
        }
Example #19
0
        public void Run()
        {
            Trace.Listeners.Add(new ConsoleTraceListener());

            const string remoteAddress = "rm://234.0.0.7:40001/";

            Guid id = CombGuid.Generate();

            ActorRegistry registry = ActorRegistryFactory.New(x =>
            {
                x.Remote(r => r.ListenTo(remoteAddress));
            });

            ActorRef server = AnonymousActor.New(inbox =>
            {
                inbox.Receive <Response <Hello> >(message =>
                {
                    Console.WriteLine("Hi!");
                    Console.WriteLine("Request ID: " + message.RequestId);
                });
            });


            registry.Register(id, server);

            var actorAddress = new ActorUrn(remoteAddress, id);

            registry.Select(actorAddress, actor =>
            {
                actor.Send <Response <Hello> >(new ResponseImpl <Hello>(new Hello
                {
                    MyNameIs = "Joe",
                }, "27"));
            }, () => {});

            ThreadUtil.Sleep(5.Seconds());

            registry.Shutdown();
        }
Example #20
0
        public void HandleStop(Request <Stop> request)
        {
            IEnumerator <ActorRef> next = _inbox.LinkedActors.GetEnumerator();

            if (next.MoveNext())
            {
                AnonymousActor.New(x => x.Loop(loop =>
                {
                    next.Current.Request <Stop>(x)
                    .Receive <Response <Stop> >(response =>
                    {
                        if (next.MoveNext())
                        {
                            loop.Continue();
                        }
                        else
                        {
                            request.Respond();
                        }
                    });
                }));
            }
        }
Example #21
0
        public void Adding_an_actor_to_a_registry()
        {
            _auctionFactory = ActorFactory.Create(inbox => new Auction(inbox));

            _auctionId = CombGuid.Generate();

            ActorRef auction = _auctionFactory.GetActor();

            ActorRegistry registry = ActorRegistryFactory.New(x =>
            {
                //x.Remote(r => r.ListenTo("rm://234.0.0.7:40001"));
            });

            registry.Register(_auctionId, auction);

            _response = new Future <Response <Bid> >();

            AnonymousActor.New(inbox =>
            {
                registry.Request <Bid>(new BidImpl(27.42m),
                                       header => { header.DestinationAddress = new ActorUrn(_auctionId); }, inbox)
                .Receive <Response <Bid> >(x => _response.Complete);
            });

            _response.WaitUntilCompleted(5.Seconds()).ShouldBeTrue();

            // need to proxy the channel with headers somehow...

            // untyped channel => channel mapper -> actor instance

            // DestinationAddress -> set by outbound channel proxy on message<>
            // SourceAddress -> set by outbound channel proxy when available (not likely)
            // ResponseAddress -> set by outbound channel for ResponseChannel on Request to map to channel
            // Id -> system assigned id
            // DestinationAddress = urn:actor:554FC958-4661-4FE9-94F5-21D190417BCC
        }
Example #22
0
        public void Should_not_require_extensive_namespace_references()
        {
            var responded = new Future <MyResponse>();

            ActorRef server = AnonymousActor.New(inbox =>
            {
                inbox.Receive <Request <MyRequest> >(request =>
                {
                    // send our response
                    request.Respond(new MyResponse());
                });
            });

            ActorRef client = AnonymousActor.New(inbox =>
            {
                server.Request(new MyRequest(), inbox)
                .Receive <Response <MyResponse> >(response => responded.Complete(response.Body));
            });

            responded.WaitUntilCompleted(2.Seconds()).ShouldBeTrue();

            server.Exit();
            client.Exit();
        }
Example #23
0
        public void Charging_an_account_async_should_still_adjust_the_balence()
        {
            ActorRef account = ActorFactory.Create(inbox => new AccountActor(inbox, 100.0m)).GetActor();

            decimal balance         = 0xDEADBEEF;
            decimal availableCredit = 0xDEADBEEF;
            decimal creditLimit     = 0xDEADBEEF;

            #region  Charge 3 times with 10.0 async

            AnonymousActor.New(inbox =>
            {
                account.Send(new ChargeAccount()
                {
                    Amount = 10
                });
            });

            AnonymousActor.New(inbox =>
            {
                account.Send(new ChargeAccount()
                {
                    Amount = 10
                });
            });

            AnonymousActor.New(inbox =>
            {
                account.Send(new ChargeAccount()
                {
                    Amount = 10
                });
            });

            #endregion

            #region Loop until available credit is correct but fail if more than 50 times

            for (int i = 0; availableCredit != 70.0m && i < 100; i++)
            {
                Future <bool> result = new Future <bool>();

                //Fire of listeners serially and with some time apart
                AnonymousActor.New(inbox =>
                {
                    account.Request(new QueryAccountBalance(), inbox)
                    .Receive <AccountBalance>(message =>
                    {
                        balance         = message.Balance;
                        availableCredit = message.AvailableCredit;
                        creditLimit     = message.CreditLimit;

                        Console.WriteLine("Balance={0}, Credit={1}, Limit={2}",
                                          balance,
                                          availableCredit,
                                          creditLimit);

                        Thread.Sleep(1000);
                        result.Complete(true);
                    });
                });
                result.WaitUntilCompleted(5.Seconds());
                Console.WriteLine("Listener {0} completed", i);
                Thread.Sleep(1000);

                Assert.True(i < 50);
            }

            #endregion

            Assert.True(balance == 30 && availableCredit == 70.0m && creditLimit == 100.0m);
        }
        public void Run()
        {
            var network = new Uri("pgm://224.0.0.7:40001");

            ActorRef actor = AnonymousActor.New(inbox =>
            {
                inbox.Loop(loop =>
                {
                    loop
                    .Receive <A>(message =>
                    {
                        Console.WriteLine("Received: " + message.Name);

                        loop.Continue();
                    })
                    .Receive <B>(message =>
                    {
                        Console.WriteLine("Received: " + message.Address);
                        loop.Continue();
                    });
                });
            });

            using (var writer = new ReliableMulticastWriter(network))
            {
                writer.Start();

                MessageHeaders.MatchHeaderChannel channel;
                using (var buffer = new BufferedChunkWriter(new PoolFiber(), new TimerScheduler(new PoolFiber()), writer, 64 * 1024))
                {
                    buffer.Start();

                    channel =
                        new MessageHeaders.MatchHeaderChannel(
                            new MatchHeaderChannel(new SerializeChunkChannel(buffer, new FastTextSerializer())));


                    MessageHeaders.MatchHeaderChannel channel2;
                    using (var buffer2 = new BufferedChunkWriter(new PoolFiber(), new TimerScheduler(new PoolFiber()), writer, 64 * 1024)
                           )
                    {
                        buffer2.Start();
                        channel2 =
                            new MessageHeaders.MatchHeaderChannel(
                                new MatchHeaderChannel(new SerializeChunkChannel(buffer2, new FastTextSerializer())));

                        Console.WriteLine("Writer started");

                        for (int i = 0; i < 10; i++)
                        {
                            channel.Send(new A
                            {
                                Name = "Joe"
                            });

                            channel2.Send(new B
                            {
                                Address = "American Way",
                            });
                        }
                        Console.WriteLine("Sent message");

                        var reader = new DeserializeChunkChannel(actor, new FastTextSerializer());

                        using (var listener = new ReliableMulticastListener(network, reader))
                        {
                            Console.WriteLine("Listener created");
                            listener.Start();

                            Console.WriteLine("Listener started");

                            Thread.Sleep(2000);

                            Console.WriteLine("Leaving Listener");
                        }

                        Console.WriteLine("Listener stopped");
                    }
                }
            }

            Console.WriteLine("Sender Stopped");
        }
Example #25
0
        public void Run()
        {
            Stopwatch timer = Stopwatch.StartNew();

            const int actorCount = 20;
            const int pingCount  = 4000;

            var actors = new ActorRef[actorCount + 1];

            var complete = new Future <int>();

            var latch = new CountdownLatch(actorCount * pingCount, complete.Complete);

            for (int i = actorCount; i >= 0; i--)
            {
                actors[i] = AnonymousActor.New(inbox =>
                {
                    var pong = new Pong();

                    var server = actors[(i + 1)];

                    inbox.Loop(loop =>
                    {
                        loop.Receive <Request <Ping> >(request =>
                        {
                            request.Respond(pong);
                            loop.Continue();
                        });
                    });


                    if (i < actorCount)
                    {
                        var ping  = new Ping();
                        int count = 0;

                        Action loop = null;
                        loop        = () =>
                        {
                            server.Request(ping, inbox)
                            .Receive <Response <Pong> >(response =>
                            {
                                latch.CountDown();
                                count++;
                                if (count < pingCount)
                                {
                                    loop();
                                }
                            });
                        };

                        loop();
                    }
                });
            }

            bool completed = complete.WaitUntilCompleted(5.Minutes());

            timer.Stop();

            for (int i = 0; i < actorCount; i++)
            {
                actors[i].Exit();
                actors[i] = null;
            }

            if (!completed)
            {
                Console.WriteLine("Process did not complete");
                return;
            }

            Console.WriteLine("Processed {0} messages in with {1} actors in {2}ms", pingCount, actorCount, timer.ElapsedMilliseconds);

            Console.WriteLine("That's {0} messages per second!", ((long)pingCount * actorCount * 2 * 1000) / timer.ElapsedMilliseconds);
        }