public static Task <bool> GracefulStop(this IActorRef target, TimeSpan timeout, object stopMessage) { var internalTarget = target.AsInstanceOf <IInternalActorRef>(); var promiseRef = PromiseActorRef.Apply(internalTarget.Provider, timeout, target, stopMessage.GetType().Name); internalTarget.SendSystemMessage(new Watch(internalTarget, promiseRef)); target.Tell(stopMessage, ActorRefs.NoSender); return(promiseRef.Result.ContinueWith(t => { var returnResult = false; PatternMatch.Match(t.Result) .With <Terminated>(terminated => { returnResult = (terminated.ActorRef.Path.Equals(target.Path)); }) .Default(m => { returnResult = false; }); internalTarget.SendSystemMessage(new Unwatch(internalTarget, promiseRef)); return returnResult; }, TaskContinuationOptions.ExecuteSynchronously)); }
protected override void OnReceive(object message) { PatternMatch.Match(message) .With <ListenerMessage>(l => Listeners.ListenerReceive(l)) .With <string>(s => { if (s.Equals("foo")) { Listeners.Gossip("bar"); } }); }
protected override void OnReceive(object message) { PatternMatch.Match(message) .With <RegisterTransportActor>(r => { /* * TODO: need to add support for RemoteDispatcher here. * See https://github.com/akka/akka/blob/master/akka-remote/src/main/scala/akka/remote/RemoteSettings.scala#L42 * and https://github.com/akka/akka/blob/master/akka-remote/src/main/scala/akka/remote/Remoting.scala#L95 */ Sender.Tell(Context.ActorOf(r.Props.WithDeploy(Deploy.Local), r.Name)); }); }
/// <summary> /// By default, <see cref="Failure"/> is logged at error level and other /// reason types are not logged. It is possible to override this behavior. /// </summary> /// <param name="reason"></param> protected virtual void LogTermination(Reason reason) { PatternMatch.Match(reason) .With <Failure>(f => { if (f.Cause is Exception) { _log.Error(f.Cause.AsInstanceOf <Exception>(), "terminating due to Failure"); } else { _log.Error(f.Cause.ToString()); } }); }
protected override void OnReceive(object message) { PatternMatch.Match(message) .With <string>(str => { if (str.Equals("bar")) { _barCount.GetAndIncrement(); _barLatch.CountDown(); } if (str.Equals("foo")) { _fooLatch.CountDown(); } }); }
protected override void OnReceive(object message) { PatternMatch.Match(message) .With <InitializeLogger>(m => Sender.Tell(new LoggerInitialized())) .With <Error>(m => Trace.TraceError(m.ToString())) .With <Warning>(m => Trace.TraceWarning(m.ToString())) .With <DeadLetter>(m => Trace.TraceWarning(string.Format("Deadletter - unable to send message {0} from {1} to {2}", m.Message, m.Sender, m.Sender), typeof(DeadLetter).ToString())) .With <UnhandledMessage>(m => Trace.TraceWarning(string.Format("Unhandled message!"), typeof(UnhandledMessage).ToString())) .Default(m => { if (m != null) { Trace.TraceInformation(m.ToString()); } }); }
public static Task <bool> GracefulStop(this ActorRef target, TimeSpan timeout, object stopMessage) { var internalTarget = target.AsInstanceOf <InternalActorRef>(); if (internalTarget.IsTerminated) { return(Task.Run(() => true)); } var provider = Futures.ResolveProvider(target); var promise = new TaskCompletionSource <object>(); //set up the timeout var cancellationSource = new CancellationTokenSource(); cancellationSource.Token.Register(() => promise.TrySetCanceled()); cancellationSource.CancelAfter(timeout); //create a new tempcontainer path var path = provider.TempPath(); //callback to unregister from tempcontainer Action unregister = () => provider.UnregisterTempActor(path); var fref = new FutureActorRef(promise, ActorRef.NoSender, unregister, path); internalTarget.Tell(new Watch(internalTarget, fref)); target.Tell(stopMessage, ActorRef.NoSender); return(promise.Task.ContinueWith(t => { var returnResult = false; PatternMatch.Match(t.Result) .With <Terminated>(terminated => { returnResult = (terminated.ActorRef.Path.Equals(target.Path)); }) .Default(m => { returnResult = false; }); internalTarget.Tell(new Unwatch(target, fref)); return returnResult; }, TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.AttachedToParent)); }
protected override void OnReceive(object message) { PatternMatch.Match(message) .With <InitializeLogger>(m => { var bus = m.LoggingBus; bus.Subscribe(this.Self, typeof(SetTarget)); bus.Subscribe(this.Self, typeof(UnhandledMessage)); Sender.Tell(new LoggerInitialized()); }) .With <SetTarget>(m => { dst = m.Ref; dst.Tell("OK"); }) .With <LogEvent>(m => dst.Tell(m)) .With <UnhandledMessage>(m => dst.Tell(m)); }
protected override void OnReceive(object message) { PatternMatch.Match(message) .With <Spawn>(m => { Context.ActorOf(Props.Create(() => new KillableActor(testActor)), m.Name); testActor.Tell(Tuple.Create("Created", m.Name)); }) .With <ContextStop>(m => { var child = Context.Child(m.Name); Context.Stop(child); }) .With <Stop>(m => { var child = Context.Child(m.Name); child.Stop(); }) .With <Count>(m => testActor.Tell(Context.GetChildren().Count())); }
public void EggsInBasket() { var eggs = 2; var basket = PatternMatch.Match() .With(() => eggs == 0, "No eggs") .With(() => eggs == 1, "One egg") .With(() => eggs > 1, string.Format("{0} eggs", eggs)) .Else("Invalid number of eggs"); var twoEggs = basket.Do(); eggs = 0; var zeroEggs = basket.Do(); eggs = int.MinValue; var invalidEggs = basket.Do(); twoEggs.ShouldBe("2 eggs"); zeroEggs.ShouldBe("No eggs"); invalidEggs.ShouldBe("Invalid number of eggs"); }
protected override void OnReceive(object message) { PatternMatch.Match(message) .With <ListenUnderlying>(listen => { localAddress = listen.ListenAddress; listen.UpstreamListener.ContinueWith( listenerRegistered => Self.Tell(new ListenerRegistered(listenerRegistered.Result)), TaskContinuationOptions.AttachedToParent); }) .With <ListenerRegistered>(listener => { associationListener = listener.Listener; foreach (var dEvent in DelayedEvents) { Self.Tell(dEvent, ActorRef.NoSender); } DelayedEvents = new Queue <object>(); Context.Become(Ready); }) .Default(m => DelayedEvents.Enqueue(m)); }
public void FirstLettersOfThings() { var processName = PatternMatch.Match <string, string>() .With(x => x.StartsWith("A"), "Starts with A") .With(x => x.StartsWith("B"), "Starts with B") .With(x => x.StartsWith("C"), "Starts with C") .With(x => x.StartsWith("D"), "Starts with D") .With(x => x.StartsWith("E"), "Starts with E") .With(x => x.StartsWith("F"), x => string.Format("{0} starts with F", x)) .Else("Unknown") .ToFunc(); var alfred = processName("Alfred"); var fiona = processName("Fiona"); var ben = processName("Ben"); var xerces = processName("Xerces"); alfred.ShouldBe("Starts with A"); fiona.ShouldBe("Fiona starts with F"); ben.ShouldBe("Starts with B"); xerces.ShouldBe("Unknown"); }
/// <summary> /// Main actor receive method /// </summary> /// <param name="message"></param> protected override bool Receive(object message) { var match = PatternMatch.Match(message) .With <TimeoutMarker>(marker => { if (_generation == marker.Generation) { ProcessMsg(new StateTimeout(), "state timeout"); } }) .With <Timer>(t => { if (_timers.ContainsKey(t.Name) && _timers[t.Name].Generation == t.Generation) { if (_timeoutFuture != null) { _timeoutFuture.Cancel(false); _timeoutFuture = null; } _generation++; if (!t.Repeat) { _timers.Remove(t.Name); } ProcessMsg(t.Message, t); } }) .With <SubscribeTransitionCallBack>(cb => { Context.Watch(cb.ActorRef); Listeners.Add(cb.ActorRef); //send the current state back as a reference point cb.ActorRef.Tell(new CurrentState <TState>(Self, _currentState.StateName)); }) .With <Listen>(l => { Context.Watch(l.Listener); Listeners.Add(l.Listener); l.Listener.Tell(new CurrentState <TState>(Self, _currentState.StateName)); }) .With <UnsubscribeTransitionCallBack>(ucb => { Context.Unwatch(ucb.ActorRef); Listeners.Remove(ucb.ActorRef); }) .With <Deafen>(d => { Context.Unwatch(d.Listener); Listeners.Remove(d.Listener); }) .With <InternalActivateFsmLogging>(_ => { DebugEvent = true; }) .Default(msg => { if (_timeoutFuture != null) { _timeoutFuture.Cancel(false); _timeoutFuture = null; } _generation++; ProcessMsg(msg, Sender); }); return(match.WasHandled); }
/// <summary> /// Main actor receive method /// </summary> /// <param name="message"></param> protected override void OnReceive(object message) { PatternMatch.Match(message) .With <TimeoutMarker>(marker => { if (generation == marker.Generation) { ProcessMsg(new StateTimeout(), "state timeout"); } }) .With <Timer>(t => { if (timers.ContainsKey(t.Name) && timers[t.Name].Generation == t.Generation) { if (timeoutFuture != null) { timeoutFuture.Cancel(false); timeoutFuture = null; } generation++; if (!t.Repeat) { timers.Remove(t.Name); } ProcessMsg(t.Message, t); } }) .With <SubscribeTransitionCallBack>(cb => { Context.Watch(cb.ActorRef); Listeners.Add(cb.ActorRef); //send the current state back as a reference point cb.ActorRef.Tell(new CurrentState <TS>(Self, currentState.StateName)); }) .With <Listen>(l => { Context.Watch(l.Listener); Listeners.Add(l.Listener); l.Listener.Tell(new CurrentState <TS>(Self, currentState.StateName)); }) .With <UnsubscribeTransitionCallBack>(ucb => { Context.Unwatch(ucb.ActorRef); Listeners.Remove(ucb.ActorRef); }) .With <Deafen>(d => { Context.Unwatch(d.Listener); Listeners.Remove(d.Listener); }) .With <Terminated>(t => Listeners.Remove(t.ActorRef)) .Default(msg => { if (timeoutFuture != null) { timeoutFuture.Cancel(false); timeoutFuture = null; } generation++; ProcessMsg(msg, Sender); }); }
protected override bool Receive(object message) { PatternMatch.Match(message) .With <Get>(get => { if (_messages.Count == 0) { EnqueueQuery(get); } else { Sender.Tell(_messages.Dequeue()); } }) .With <Select>(select => { if (_messages.Count == 0) { EnqueueQuery(select); } else { _currentSelect = select; var firstMatch = _messages.DequeueFirstOrDefault(MessagePredicate); if (firstMatch == null) { EnqueueQuery(select); } else { Sender.Tell(firstMatch); } _currentSelect = null; } }) .With <StartWatch>(sw => Context.Watch(sw.Target)) .With <Kick>(() => { var now = DateTime.Now; var overdue = _clientsByTimeout.TakeWhile(q => q.Deadline < now); foreach (var query in overdue) { query.Client.Tell(new Status.Failure(new TimeoutException("Deadline passed"))); } _clients.RemoveAll(q => q.Deadline < now); var afterDeadline = _clientsByTimeout.Where(q => q.Deadline >= now).ToList(); _clientsByTimeout.IntersectWith(afterDeadline); }).Default(msg => { if (_clients.Count == 0) { EnqueueMessage(msg); } else { _currentMessage = msg; var firstMatch = _clients.DequeueFirstOrDefault(ClientPredicate); //TODO: this should work as DequeueFirstOrDefault if (firstMatch != null) { _clientsByTimeout.ExceptWith(new[] { firstMatch }); firstMatch.Client.Tell(msg); } else { EnqueueMessage(msg); } _currentMessage = null; } }); if (_clients.Count == 0) { if (_currentDeadline != null) { _currentDeadline.Item2.Cancel(); _currentDeadline = null; } } else { var next = _clientsByTimeout.FirstOrDefault(); if (next != null) { if (_currentDeadline != null) { _currentDeadline.Item2.Cancel(); } var cancellationTokenSource = new CancellationTokenSource(); Context.System.Scheduler.ScheduleOnce(next.Deadline - DateTime.Now, Self, new Kick(), cancellationTokenSource.Token); _currentDeadline = Tuple.Create(next.Deadline, cancellationTokenSource); } } return(true); }
protected override void OnReceive(object message) { PatternMatch.Match(message) .With <Tuple <TestLatch, TimeSpan> >(t => t.Item1.Ready(t.Item2)); }
protected void SendSystemMessage(SystemMessage message, ActorRef sender) { PatternMatch.Match(message) .With <Terminate>(t => Stop()) .With <DeathWatchNotification>(d => Tell(new Terminated(d.Actor, d.ExistenceConfirmed, d.AddressTerminated))); }