public ListenerActor(TestLatch fooLatch, TestLatch barLatch, AtomicCounter barCount) { _fooLatch = fooLatch; _barLatch = barLatch; _barCount = barCount; Listeners = new ListenerSupport(); }
public LifeCycleTest2Actor(ActorRef testActor, string id, AtomicCounter generationProvider) { this.testActor = testActor; this.id = id; this.generationProvider = generationProvider; this.CurrentGeneration = generationProvider.Next(); }
public void Listener_must_listen_in() { //arrange var fooLatch = new TestLatch(Sys, 2); var barLatch = new TestLatch(Sys, 2); var barCount = new AtomicCounter(0); var broadcast = Sys.ActorOf<BroadcastActor>(); var newListenerProps = Props.Create(() => new ListenerActor(fooLatch, barLatch, barCount)); var a1 = Sys.ActorOf(newListenerProps); var a2 = Sys.ActorOf(newListenerProps); var a3 = Sys.ActorOf(newListenerProps); //act broadcast.Tell(new Listen(a1)); broadcast.Tell(new Listen(a2)); broadcast.Tell(new Listen(a3)); broadcast.Tell(new Deafen(a3)); broadcast.Tell(new WithListeners(a => a.Tell("foo"))); broadcast.Tell("foo"); //assert barLatch.Ready(TestLatch.DefaultTimeout); Assert.Equal(2, barCount.Current); fooLatch.Ready(TestLatch.DefaultTimeout); foreach (var actor in new[] {a1, a2, a3, broadcast}) { Sys.Stop(actor); } }
public void BroadcastGroup_router_must_broadcast_message_using_Ask() { var doneLatch = new TestLatch(Sys, 2); var counter1 = new AtomicCounter(0); var counter2 = new AtomicCounter(0); var actor1 = Sys.ActorOf(Props.Create(() => new BroadcastTarget(doneLatch, counter1))); var actor2 = Sys.ActorOf(Props.Create(() => new BroadcastTarget(doneLatch, counter2))); var routedActor = Sys.ActorOf(Props.Create<TestActor>().WithRouter(new BroadcastGroup(actor1.Path.ToString(), actor2.Path.ToString()))); routedActor.Ask(new Broadcast(1)); routedActor.Tell(new Broadcast("end")); doneLatch.Ready(TimeSpan.FromSeconds(1)); counter1.Current.ShouldBe(1); counter2.Current.ShouldBe(1); }
/// <summary> /// Sends a message to the collection of routees. /// </summary> /// <param name="message">The message that is being sent.</param> /// <param name="sender">The actor sending the message.</param> public override void Send(object message, IActorRef sender) { _routees.Shuffle(); var routeeIndex = new AtomicCounter(0); var completion = new TaskCompletionSource<object>(); var cancelable = new Cancelable(_scheduler); completion.Task .ContinueWith(task => cancelable.Cancel(false)); if (_routees.Length == 0) { completion.TrySetResult(NoRoutee); } else { _scheduler.Advanced.ScheduleRepeatedly(TimeSpan.Zero, _interval, async () => { var currentIndex = routeeIndex.GetAndIncrement(); if (currentIndex >= _routees.Length) return; try { completion.TrySetResult(await ((Task<object>)_routees[currentIndex].Ask(message, _within))); } catch (TaskCanceledException) { completion.TrySetResult( new Status.Failure( new AskTimeoutException(String.Format("Ask timed out on {0} after {1}", sender, _within)))); } }, cancelable); } completion.Task.PipeTo(sender); }
public void ActorLifecycleTest3() { var generationProvider = new AtomicCounter(); string id = Guid.NewGuid().ToString(); var supervisor = Sys.ActorOf(Props.Create(() => new Supervisor(new OneForOneStrategy(3, TimeSpan.FromSeconds(1000), x => Directive.Restart)))); var restarterProps = Props.Create(() => new LifeCycleTest2Actor(TestActor, id, generationProvider)); var restarter = supervisor.Ask<InternalActorRef>(restarterProps).Result; ExpectMsg(Tuple.Create("preStart", id, 0)); restarter.Tell("status"); ExpectMsg(Tuple.Create("OK", id, 0)); restarter.Stop(); ExpectMsg(Tuple.Create("postStop", id, 0)); ExpectNoMsg(TimeSpan.FromSeconds(1)); }
public BroadcastTarget(TestLatch latch, AtomicCounter counter) { _latch = latch; _counter = counter; }
public void Tail_chopping_router_must_deliver_a_broadcast_message_using_tell() { var doneLatch = new TestLatch(Sys, 2); var counter1 = new AtomicCounter(0); var counter2 = new AtomicCounter(0); var actor1 = Sys.ActorOf(Props.Create(() => new BroadcastTarget(doneLatch, counter1)), "Actor1"); var actor2 = Sys.ActorOf(Props.Create(() => new BroadcastTarget(doneLatch, counter2)), "Actor2"); var routedActor = Sys.ActorOf(Props.Create<TestActor>() .WithRouter(new TailChoppingGroup(new string[] { actor1.Path.ToString(), actor2.Path.ToString() }, TimeSpan.FromSeconds(1), TimeSpan.FromMilliseconds(100)) )); routedActor.Tell(new Broadcast(1)); routedActor.Tell(new Broadcast("end")); doneLatch.Ready(TimeSpan.FromSeconds(1)); counter1.Current.ShouldBe(1); counter2.Current.ShouldBe(1); }
public void A_Flow_with_SelectAsync_must_not_run_more_futures_than_configured() { this.AssertAllStagesStopped(() => { const int parallelism = 8; var counter = new AtomicCounter(); var queue = new BlockingQueue<Tuple<TaskCompletionSource<int>, long>>(); var timer = new Thread(() => { var delay = 500; // 50000 nanoseconds var count = 0; var cont = true; while (cont) { try { var t = queue.Take(CancellationToken.None); var promise = t.Item1; var enqueued = t.Item2; var wakeup = enqueued + delay; while (DateTime.Now.Ticks < wakeup) { } counter.Decrement(); promise.SetResult(count); count++; } catch { cont = false; } } }); timer.Start(); Func<Task<int>> deferred = () => { var promise = new TaskCompletionSource<int>(); if (counter.IncrementAndGet() > parallelism) promise.SetException(new Exception("parallelism exceeded")); else queue.Enqueue(Tuple.Create(promise, DateTime.Now.Ticks)); return promise.Task; }; try { const int n = 10000; var task = Source.From(Enumerable.Range(1, n)) .SelectAsync(parallelism, _ => deferred()) .RunAggregate(0, (c, _) => c + 1, Materializer); task.Wait(TimeSpan.FromSeconds(3)).Should().BeTrue(); task.Result.Should().Be(n); } finally { timer.Interrupt(); } }, Materializer); }
/// <summary> /// Sends a message to the tail chopping router's collection of routees. /// </summary> /// <param name="message">The message to send.</param> /// <param name="sender">The sender of the message.</param> public override void Send(object message, ActorRef sender) { routees.Shuffle(); var routeeIndex = new AtomicCounter(0); var completion = new TaskCompletionSource<object>(); var tokenSource = new CancellationTokenSource(); var token = tokenSource.Token; var scheduledSends = scheduler.Schedule(TimeSpan.Zero, interval, async () => { var currentIndex = routeeIndex.GetAndIncrement(); if(currentIndex < routees.Length) { completion.TrySetResult(await ((Task<object>)routees[currentIndex].Ask(message, null))); } }, token); var withinTimeout = scheduler.ScheduleOnce(within, () => { completion.TrySetException(new TimeoutException(String.Format("Ask timed out on {0} after {1}", sender, within))); }, token); var request = completion.Task; completion.Task.ContinueWith((task) => { tokenSource.Cancel(false); }); request.PipeTo(sender); }