public ClusterMetricsCollector(IActorRef publisher) { _publisher = publisher; _cluster = Cluster.Get(Context.System); Collector = MetricsCollector.Get(Context.System.AsInstanceOf<ExtendedActorSystem>(), _cluster.Settings); LatestGossip = MetricsGossip.Empty; Nodes = ImmutableHashSet.Create<Address>(); _metricsCancelable = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable( _cluster.Settings.PeriodicTasksInitialDelay.Max(_cluster.Settings.MetricsInterval), _cluster.Settings.MetricsInterval, Self, InternalClusterAction.MetricsTick.Instance, Self); _gossipCancelable = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable( _cluster.Settings.PeriodicTasksInitialDelay.Max(_cluster.Settings.GossipInterval), _cluster.Settings.GossipInterval, Self, InternalClusterAction.GossipTick.Instance, Self); Receive<InternalClusterAction.GossipTick>(tick => Gossip()); Receive<InternalClusterAction.MetricsTick>(tick => Collect()); Receive<MetricsGossipEnvelope>(envelope => ReceiveGossip(envelope)); Receive<ClusterEvent.CurrentClusterState>(state => ReceiveState(state)); Receive<ClusterEvent.MemberUp>(up => AddMember(up.Member)); Receive<ClusterEvent.MemberRemoved>(removed => RemoveMember(removed.Member)); Receive<ClusterEvent.MemberExited>(exited => RemoveMember(exited.Member)); Receive<ClusterEvent.UnreachableMember>(member => RemoveMember(member.Member)); Receive<ClusterEvent.ReachableMember>(member => { if (member.Member.Status == MemberStatus.Up) AddMember(member.Member); }); Receive<ClusterEvent.IMemberEvent>(@event => { }); //not interested in other types of member event }
private void receiveEngineRunCommand(MessageEngineRunCommand msg) { MessageTick pulse = new MessageTick(0); if (msg.RunCommand == EngineRunCommand.RunMax && _runState != TickEngineRunState.RunningMax) { cancelPulse(); _numberOfIncompleteSS = _subscribedActorSolarSystems.Count(); _runState = TickEngineRunState.RunningMax; startTicksTimer(); receiveTick(pulse); } else if (msg.RunCommand == EngineRunCommand.RunPulse && _runState != TickEngineRunState.Running) { _runState = TickEngineRunState.Running; _runCancel = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable(0, 5, Self, pulse, ActorRefs.Nobody); startTicksTimer(); receiveTick(pulse); } else if (msg.RunCommand == EngineRunCommand.Stop && _runState != TickEngineRunState.Stopped) { _runState = TickEngineRunState.Stopped; cancelPulse(); _secondTimer.Stop(); } }
public PerformanceCounterActor(string seriesName, Func<PerformanceCounter> performanceCounterGenerator) { _seriesName = seriesName; _performanceCounterGenerator = performanceCounterGenerator; _subscriptions = new HashSet<IActorRef>(); _cancelPublishing = new Cancelable(Context.System.Scheduler); Receive<GatherMetrics>(m => { //publish latest counter value to all subscribers var metric = new Metric(_seriesName, _counter.NextValue()); foreach (var sub in _subscriptions) sub.Tell(metric); }); Receive<SubscribeCounter>(sc => { // add a subscription for this counter // (it's parent's job to filter by counter types) _subscriptions.Add(sc.Subscriber); }); Receive<UnsubscribeCounter>(uc => { // remove a subscription from this counter _subscriptions.Remove(uc.Subscriber); }); }
protected TopicLike(TimeSpan emptyTimeToLive) { Subscribers = new HashSet<IActorRef>(); EmptyTimeToLive = emptyTimeToLive; PruneInterval = new TimeSpan(emptyTimeToLive.Ticks / 2); PruneCancelable = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable(PruneInterval, PruneInterval, Self, Prune.Instance, Self); }
protected override void PreStart() { _cluster = Cluster.Get(Context.System); _cancelStatusUpdates = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(2), Self, new SendState(), Self); base.PreStart(); }
/// <summary> /// Create a new <see cref="PerformanceCounterMonitor"/> actor. /// </summary> /// <param name="seriesName"> /// The name of the data series that tracks the performance counter's value. /// </param> /// <param name="performanceCounterFactory"> /// A factory delegate that creates the <see cref="PerformanceCounter"/> to monitor. /// </param> public PerformanceCounterMonitor(string seriesName, Func<PerformanceCounter> performanceCounterFactory) { if (String.IsNullOrWhiteSpace(seriesName)) throw new ArgumentException("Argument cannot be null, empty, or entirely componsed of whitespace: 'seriesName'.", nameof(seriesName)); if (performanceCounterFactory == null) throw new ArgumentNullException(nameof(performanceCounterFactory)); _seriesName = seriesName; _performanceCounterFactory = performanceCounterFactory; _cancelPublishing = new Cancelable(Context.System.Scheduler); Receive<GatherMetrics>(_ => { Metric metric = new Metric( _seriesName, _performanceCounter.NextValue() ); foreach (IActorRef subscriber in _subscribers) subscriber.Tell(metric); }); Receive<SubscribePerformanceCounter>(request => { _subscribers.Add(request.Subscriber); }); Receive<UnsubscribePerformanceCounter>(request => { _subscribers.Remove(request.Subscriber); }); }
public PerformanceCounterActor(string seriesName, Func<PerformanceCounter> performanceCounterGenerator) { _seriesName = seriesName; _performanceCounterGenerator = performanceCounterGenerator; _subscriptions = new HashSet<IActorRef>(); _cancelPublishing = new Cancelable(Context.System.Scheduler); }
public SignalRClusterStatusActor() { ClusterStatusTeller = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(1), Self, new ClusterStatus.SendCurrentClusterState(), Self); Ready(); }
IEnumerator PeriodicAction(TimeSpan period, Action action, ICancelable cancellation) { // zero == every frame if (period == TimeSpan.Zero) { while (true) { yield return null; // not immediately, run next frame if (cancellation.IsDisposed) yield break; MainThreadDispatcher.UnsafeSend(action); } } else { var seconds = (float)(period.TotalMilliseconds / 1000.0); var yieldInstruction = new WaitForSeconds(seconds); // cache single instruction object while (true) { yield return yieldInstruction; if (cancellation.IsDisposed) yield break; MainThreadDispatcher.UnsafeSend(action); } } }
public SignalRItemStatusActor() { ItemSubscriberTeller = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(2), Self, new SubscribeToWorkers(), Self); Ready(); }
private void Timeout() { _timedOut = true; _cancelHeartbeat?.Cancel(false); _cancelHeartbeat = null; Context.Parent.Tell(new ConnectionMessages.ConnectionLost()); }
public ClusterServiceStatusActor() { _cancel = new CancellationTokenSource(); ClusterServiceStatusTeller = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(1), Self, new GetServiceStatus(), Self); Ready(); }
protected override void InternalScheduleTellOnce(TimeSpan delay, ICanTell receiver, object message, IActorRef sender, ICancelable cancelable) { var cancellationToken = cancelable == null ? CancellationToken.None : cancelable.Token; InternalScheduleOnce(delay, () => { receiver.Tell(message, sender); }, cancellationToken); }
private void CancelReceiveTimeout() { if (_pendingReceiveTimeout != null) { _pendingReceiveTimeout.Cancel(); _pendingReceiveTimeout = null; } }
public void CheckReceiveTimeout() { CancelReceiveTimeout(); if (_receiveTimeoutDuration != null && !Mailbox.HasMessages) { _pendingReceiveTimeout = System.Scheduler.ScheduleTellOnceCancelable(_receiveTimeoutDuration.Value, Self, ReceiveTimeout.Instance, Self); } }
public ClusterManager() { _clusterStartTime = DateTime.Now; Cluster.Subscribe(Self, ClusterEvent.InitialStateAsEvents, new[] { typeof(ClusterEvent.IMemberEvent), typeof(ClusterEvent.IReachabilityEvent) }); _currentClusterStateTeller = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable(TimeSpan.FromMilliseconds(10), TimeSpan.FromSeconds(2), Self, new SendCurrentClusterState(), Self); Ready(); }
protected override void PreStart() { _cancelOutput = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable( TimeSpan.FromMilliseconds(800), TimeSpan.FromMilliseconds(200), Self, new WriteClientList(), Self); }
/* private async void HandleSendPayment(SendPaymentMessage message) { var sender = Sender; var result = await _paymentGateway.Pay(message.AccountNumber, message.Amount); sender.Tell(new PaymentSentMessage(result.AccountNumber, result.PaymentConfirmationReceipt)); } private void HandleSendPayment(SendPaymentMessage message) { var result = _paymentGateway.Pay(message.AccountNumber, message.Amount).Result; Sender.Tell(new PaymentSentMessage(result.AccountNumber, result.PaymentConfirmationReceipt)); } */ protected override void PreStart() { _unstashSchedule = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable( TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), Self, new ProcessStashedPaymentsMessage(), Self); }
private void BecomeWorking(RepoKey repo) { _receivedInitialUsers = false; _currentRepo = repo; _subscribers = new HashSet<IActorRef>(); _similarRepos = new Dictionary<string, SimilarRepo>(); _publishTimer = new Cancelable(Context.System.Scheduler); _githubProgressStats = new GithubProgressStats(); Become(Working); }
private void HandleHeartBeat() { _lastHeard = Context.System.Scheduler.Now; Context.System.ActorSelection(Addresses.ConsoleWriter.Path).Tell(new MachineStatus(_machineName, true, _lastHeard, null)); if (_cancelable != null) _cancelable.Cancel(); _cancelable = Context.System.Scheduler.ScheduleTellOnceCancelable(TimeSpan.FromSeconds(2), Self, new Flatlined(), Self); }
protected override void PreStart() { _priceRefreshing = Context.System .Scheduler .ScheduleTellRepeatedlyCancelable( TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), Self, new RefreshStockPriceMessage(_stockSymbol), Self); }
public TcpGateway(GatewayInitiator initiator) { _initiator = initiator; _logger = initiator.GatewayLogger; if (initiator.TokenRequired && initiator.TokenTimeout != TimeSpan.Zero) { _timeoutCanceler = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable( initiator.TokenTimeout, initiator.TokenTimeout, Self, new TimeoutTimerMessage(), Self); } }
// delay action is run in StartCoroutine // Okay to action run synchronous and guaranteed run on MainThread IEnumerator DelayAction(TimeSpan dueTime, Action action, ICancelable cancellation) { #if UNITY_EDITOR if (!ScenePlaybackDetector.IsPlaying) { var startTime = DateTimeOffset.UtcNow; while (true) { yield return null; if (cancellation.IsDisposed) break; var elapsed = DateTimeOffset.UtcNow - startTime; if (elapsed >= dueTime) { MainThreadDispatcher.UnsafeSend(action); break; } }; yield break; } #endif if (dueTime == TimeSpan.Zero) { yield return null; // not immediately, run next frame if (cancellation.IsDisposed) yield break; MainThreadDispatcher.UnsafeSend(action); } else if (dueTime.TotalMilliseconds % 1000 == 0) { yield return new WaitForSeconds((float)dueTime.TotalSeconds); if (cancellation.IsDisposed) yield break; MainThreadDispatcher.UnsafeSend(action); } else { var startTime = Time.time; var dt = (float)dueTime.TotalSeconds; while (true) { yield return null; if (cancellation.IsDisposed) break; var elapsed = Time.time - startTime; if (elapsed >= dt) { MainThreadDispatcher.UnsafeSend(action); break; } } } }
protected override void PreStart() { _counter = new PerformanceCounter( PerformanceCounterHelper.MainCategory, PerformanceCounterHelper.GetPerformanceCounterName( StatisticType.AvgAppointmentDuration, _hospital.Id ), false); _counter.RawValue = 0; _patients = new Dictionary<int, DateTime>(); _avgDuration = 0.0d; _statCount = 0; _cancelPublishing = ScheduleGatherStatsTask(); }
private void HandleBeginHeartbeat(BeginHeartbeat msg) { _status = msg.Status; _target = msg.HeartbeatTarget; _cancelHeartbeat = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable( TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), Self, new SendHeartbeat(), Self); }
/// <summary> /// Called when the actor is started. /// </summary> protected override void PreStart() { base.PreStart(); _repeatCancellation = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable( initialDelay: TimeSpan.FromSeconds(3), interval: TimeSpan.FromSeconds(3), receiver: Self, message: DoBroadcast.Instance, sender: Self ); }
protected override void PreStart() { _counter = new PerformanceCounter( PerformanceCounterHelper.MainCategory, PerformanceCounterHelper.GetPerformanceCounterName( StatisticType.AvgTimeToSeeADoctor, _hospital.Id ), false ); _counter.RawValue = 0; _msgPerSecondCounter = new PerformanceCounter( PerformanceCounterHelper.MainCategory, $"(H{_hospital.Id}) Messages par seconde pour {PerformanceCounterHelper.CounterAvgTimeToSeeADoctor}", false ); _patients = new Dictionary<int, DateTime>(); _avgDuration = 0.0d; _statCount = 0; _cancelPublishing = ScheduleGatherStatsTask(); }
private void AcceptingJob() { Receive<RecommendationJob>(job => { Console.WriteLine($"Starting recommendation workflow for user {job.UserId}"); _startAttempts = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable( TimeSpan.Zero, TimeSpan.FromMilliseconds(200), Self, new BeginAttempt(job), ActorRefs.NoSender); Become(Working); }); }
private void StartedState() { Receive<Collect>(msg => { _timeOutCancelable = Context.System.Scheduler.ScheduleTellOnceCancelable( _timeOut, Self, new ReadTimedOut(), Self); Context.ActorSelection(ActorNames.DriverSibling).Tell(new DriverActor.ReadChannel(_channelName)); Become(WaitingForReadResultsState); }); }
public ActiveUsersActor() { //init socket etc _activeUsers = new List<ActiveUser>(); _cancelPinging = new Cancelable(Context.System.Scheduler); _log.Warning("Started actor"); Receive<InitializeInbox>(msg => { _log.Info("Initializing inbox"); _webserviceInbox = Sender; Sender.Tell("Sure!"); }); //Received from login/register services Receive<AddUserMessage>(msg => { _log.Info("Adding user"); var response = AddUser(msg); Sender.Tell(response, Self); }); //Scheduled to run once per minute Receive<GetInactiveUsersPing>(msg => { _log.Info("Checking expired users"); if (_webserviceInbox == null) { return; } for (int i = _activeUsers.Count - 1; i >= 0; i--) { var user = _activeUsers[i]; _log.Info("Checking user " + user.Username + " - " + user.Expiration.ToLongTimeString()); if (DateTime.UtcNow > user.Expiration) { _log.Info("User " + user.Username + " has expired"); _webserviceInbox.Tell(new ExpireUser(user.Username)); _activeUsers.RemoveAt(i); } } }); Receive<ReceivedPingFromUser>(msg => { _log.Info("Received ping from user " + msg.User); _activeUsers.Single(u => u.Username == msg.User).LastPing = DateTime.UtcNow; }); }
private void SchedulePoolTask() { _poolCancellation?.Cancel(); // Stop existing scheduling, if any _poolCancellation = Context.System.Scheduler.ScheduleTellOnceCancelable(_settings.PollInterval, Self, _pollMessage, Self); }
/// <summary> /// Cancels the target. /// </summary> /// <param name="cancelTarget">The cancel target.</param> /// <returns><paramref name="cancelTarget"/> for chaining additional calls</returns> public C CancelTarget <C>(C cancelTarget) where C : ICancelable { _cancelTarget = cancelTarget; return(cancelTarget); }
protected override void InternalScheduleTellOnce(TimeSpan delay, ICanTell receiver, object message, IActorRef sender, ICancelable cancelable) { var cancellationToken = cancelable == null ? CancellationToken.None : cancelable.Token; InternalScheduleOnce(delay, () => receiver.Tell(message, sender), cancellationToken); }
void IActionScheduler.ScheduleRepeatedly(TimeSpan initialDelay, TimeSpan interval, Action action, ICancelable cancelable) { ValidateDelay(initialDelay, "initialDelay"); ValidateInterval(interval, "interval"); InternalScheduleRepeatedly(initialDelay, interval, action, cancelable); }
void ITellScheduler.ScheduleTellRepeatedly(TimeSpan initialDelay, TimeSpan interval, ICanTell receiver, object message, IActorRef sender, ICancelable cancelable) { ValidateDelay(initialDelay, "initialDelay"); ValidateInterval(interval, "interval"); InternalScheduleTellRepeatedly(initialDelay, interval, receiver, message, sender, cancelable); }
protected abstract void InternalScheduleRepeatedly(TimeSpan initialDelay, TimeSpan interval, Action action, ICancelable cancelable);
protected abstract void InternalScheduleTellRepeatedly(TimeSpan initialDelay, TimeSpan interval, ICanTell receiver, object message, IActorRef sender, ICancelable cancelable);
/// <summary> /// Schedules an action to be invoked after an delay. The action is wrapped so that it /// completes inside the currently active actor if it is called from within an actor. /// <remarks>Note! It's considered bad practice to use concurrency inside actors, and very easy to get wrong so usage is discouraged.</remarks> /// </summary> /// <param name="scheduler">The scheduler used to schedule the invocation of the action.</param> /// <param name="millisecondsDelay">The time in milliseconds that has to pass before the action is invoked.</param> /// <param name="action">The action that is being scheduled.</param> /// <param name="cancelable">OPTIONAL. A cancelable that can be used to cancel the action from being executed. Defaults to <c>null</c></param> public static void ScheduleOnce(this IActionScheduler scheduler, int millisecondsDelay, Action action, ICancelable cancelable = null) { scheduler.ScheduleOnce(TimeSpan.FromMilliseconds(millisecondsDelay), action, cancelable); }
public DistributedPubSubMediator(DistributedPubSubSettings settings) { if (settings.RoutingLogic is ConsistentHashingRoutingLogic) { throw new ArgumentException("Consistent hashing routing logic cannot be used by the pub-sub mediator"); } _settings = settings; if (!string.IsNullOrEmpty(_settings.Role) && !_cluster.SelfRoles.Contains(_settings.Role)) { throw new ArgumentException(string.Format("The cluster member [{0}] doesn't have the role [{1}]", _cluster.SelfAddress, _settings.Role)); } //Start periodic gossip to random nodes in cluster _gossipCancelable = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable(_settings.GossipInterval, _settings.GossipInterval, Self, GossipTick.Instance, Self); _pruneInterval = new TimeSpan(_settings.RemovedTimeToLive.Ticks / 2); _pruneCancelable = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable(_pruneInterval, _pruneInterval, Self, Prune.Instance, Self); Receive <Send>(send => { var routees = new List <Routee>(); Bucket bucket; if (_registry.TryGetValue(_cluster.SelfAddress, out bucket)) { ValueHolder valueHolder; if (bucket.Content.TryGetValue(send.Path, out valueHolder) && send.LocalAffinity) { var routee = valueHolder.Routee; if (routee != null) { routees.Add(routee); } } else { foreach (var entry in _registry) { if (entry.Value.Content.TryGetValue(send.Path, out valueHolder)) { var routee = valueHolder.Routee; if (routee != null) { routees.Add(routee); } } } } } if (routees.Count != 0) { new Router(_settings.RoutingLogic, routees.ToArray()).Route(Utils.WrapIfNeeded(send.Message), Sender); } }); Receive <SendToAll>(sendToAll => { PublishMessage(sendToAll.Path, sendToAll.Message, sendToAll.ExcludeSelf); }); Receive <Publish>(publish => { var topic = Uri.EscapeDataString(publish.Topic); var path = Self.Path / topic; if (publish.SendOneMessageToEachGroup) { PublishToEachGroup(path.ToStringWithoutAddress(), publish.Message); } else { PublishMessage(path.ToStringWithoutAddress(), publish.Message); } }); Receive <Put>(put => { if (!string.IsNullOrEmpty(put.Ref.Path.Address.Host)) { Log.Warning("Registered actor must be local: [{0}]", put.Ref); } else { PutToRegistry(put.Ref.Path.ToStringWithoutAddress(), put.Ref); Context.Watch(put.Ref); } }); Receive <Remove>(remove => { Bucket bucket; if (_registry.TryGetValue(_cluster.SelfAddress, out bucket)) { ValueHolder valueHolder; if (bucket.Content.TryGetValue(remove.Path, out valueHolder) && valueHolder.Ref != null) { Context.Unwatch(valueHolder.Ref); PutToRegistry(remove.Path, null); } } }); Receive <Subscribe>(subscribe => { // each topic is managed by a child actor with the same name as the topic var topic = Uri.EscapeDataString(subscribe.Topic); var child = Context.Child(topic); if (!ActorRefs.Nobody.Equals(child)) { child.Forward(subscribe); } else { var t = Context.ActorOf(Actor.Props.Create(() => new Topic(_settings.RemovedTimeToLive, _settings.RoutingLogic)), topic); t.Forward(subscribe); HandleRegisterTopic(t); } }); Receive <RegisterTopic>(register => { HandleRegisterTopic(register.TopicRef); }); Receive <GetTopics>(getTopics => { Sender.Tell(new CurrentTopics(GetCurrentTopics().ToArray())); }); Receive <Subscribed>(subscribed => { subscribed.Subscriber.Tell(subscribed.Ack); }); Receive <Unsubscribe>(unsubscribe => { var topic = Uri.EscapeDataString(unsubscribe.Topic); var child = Context.Child(topic); if (!ActorRefs.Nobody.Equals(child)) { child.Forward(unsubscribe); } }); Receive <Unsubscribed>(unsubscribed => { unsubscribed.Subscriber.Tell(unsubscribed.Ack); }); Receive <Status>(status => { // gossip chat starts with a Status message, containing the bucket versions of the other node var delta = CollectDelta(status.Versions).ToArray(); if (delta.Length != 0) { Sender.Tell(new Delta(delta)); } if (OtherHasNewerVersions(status.Versions)) { Sender.Tell(new Status(OwnVersions)); } }); Receive <Delta>(delta => { // reply from Status message in the gossip chat // the Delta contains potential updates (newer versions) from the other node // only accept deltas/buckets from known nodes, otherwise there is a risk of // adding back entries when nodes are removed if (_nodes.Contains(Sender.Path.Address)) { foreach (var bucket in delta.Buckets) { if (_nodes.Contains(bucket.Owner)) { Bucket myBucket; if (!_registry.TryGetValue(bucket.Owner, out myBucket)) { myBucket = new Bucket(bucket.Owner); } if (bucket.Version > myBucket.Version) { _registry.Add(bucket.Owner, new Bucket(myBucket.Owner, bucket.Version, myBucket.Content.AddRange(bucket.Content))); } } } } }); Receive <GossipTick>(_ => HandleGossip()); Receive <Prune>(_ => HandlePrune()); Receive <Terminated>(terminated => { var key = terminated.ActorRef.Path.ToStringWithoutAddress(); Bucket bucket; if (_registry.TryGetValue(_cluster.SelfAddress, out bucket)) { ValueHolder holder; if (bucket.Content.TryGetValue(key, out holder) && terminated.ActorRef.Equals(holder.Ref)) { PutToRegistry(key, null); // remove } } }); Receive <ClusterEvent.CurrentClusterState>(state => { var nodes = state.Members .Where(m => m.Status != MemberStatus.Joining && IsMatchingRole(m)) .Select(m => m.Address); _nodes = new HashSet <Address>(nodes); }); Receive <ClusterEvent.MemberUp>(up => { if (IsMatchingRole(up.Member)) { _nodes.Add(up.Member.Address); } }); Receive <ClusterEvent.MemberRemoved>(removed => { var member = removed.Member; if (member.Address == _cluster.SelfAddress) { Context.Stop(Self); } else if (IsMatchingRole(member)) { _nodes.Remove(member.Address); _registry.Remove(member.Address); } }); Receive <ClusterEvent.IMemberEvent>(_ => { /* ignore */ }); Receive <Count>(_ => { var count = _registry.Sum(entry => entry.Value.Content.Count(kv => kv.Value.Ref != null)); Sender.Tell(count); }); }
/// <summary> /// Schedules a message to be sent once after a specified period of time. /// </summary> /// <param name="scheduler">The scheduler used to schedule the sending of the message.</param> /// <param name="millisecondsDelay">The time in milliseconds that has to pass before the message is sent.</param> /// <param name="receiver">The actor that receives the message.</param> /// <param name="message">The message that is being sent.</param> /// <param name="sender">The actor that sent the message.</param> /// <param name="cancelable">OPTIONAL. An <see cref="ICancelable"/> used to cancel sending the message. Once the message has been sent, it cannot be canceled.</param> public static void ScheduleTellOnce(this ITellScheduler scheduler, int millisecondsDelay, ICanTell receiver, object message, IActorRef sender, ICancelable cancelable = null) { scheduler.ScheduleTellOnce(TimeSpan.FromMilliseconds(millisecondsDelay), receiver, message, sender, cancelable); }
/// <summary> /// Schedules an action to be invoked after an initial delay and then repeatedly. /// The action is wrapped so that it completes inside the currently active actor /// if it is called from within an actor. /// <remarks>Note! It's considered bad practice to use concurrency inside actors, and very easy to get wrong so usage is discouraged.</remarks> /// </summary> /// <param name="scheduler">The scheduler used to schedule the invocation of the action.</param> /// <param name="initialMillisecondsDelay">The time in milliseconds that has to pass before first invocation of the action.</param> /// <param name="millisecondsInterval">The time in milliseconds that has to pass between each invocation of the action.</param> /// <param name="action">The action that is being scheduled.</param> /// <param name="cancelable">OPTIONAL. A cancelable used to cancel the action from being executed. Defaults to <c>null</c></param> public static void ScheduleRepeatedly(this IActionScheduler scheduler, int initialMillisecondsDelay, int millisecondsInterval, Action action, ICancelable cancelable = null) { scheduler.ScheduleRepeatedly(TimeSpan.FromMilliseconds(initialMillisecondsDelay), TimeSpan.FromMilliseconds(millisecondsInterval), action, cancelable); }
/// <summary> /// Schedules a message to be sent repeatedly after an initial delay. /// </summary> /// <param name="scheduler">The scheduler used to schedule the sending of the message.</param> /// <param name="initialMillisecondsDelay">The time in milliseconds that has to pass before the first message is sent.</param> /// <param name="millisecondsInterval">The time in milliseconds that has to pass between sending of the message.</param> /// <param name="receiver">The actor that receives the message.</param> /// <param name="message">The message that is being sent.</param> /// <param name="sender">The actor that sent the message.</param> /// <param name="cancelable">OPTIONAL. An <see cref="ICancelable"/> used to cancel sending the message. Once the message has been sent, it cannot be canceled.</param> public static void ScheduleTellRepeatedly(this ITellScheduler scheduler, int initialMillisecondsDelay, int millisecondsInterval, ICanTell receiver, object message, IActorRef sender, ICancelable cancelable = null) { scheduler.ScheduleTellRepeatedly(TimeSpan.FromMilliseconds(initialMillisecondsDelay), TimeSpan.FromMilliseconds(millisecondsInterval), receiver, message, sender, cancelable); }
private ICancelable CreatePruneTask() { return(_pruneTask = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable(Settings.PruneInterval, Settings.PruneInterval, Self, PruneSendersTick.Instance, ActorRefs.NoSender)); }
private void DrainQueue(ICancelable cancel) { while (true) { #if !NO_CDS try { _evt.Wait(_stop.Token); } catch (OperationCanceledException) { return; } #else _evt.WaitOne(); if (_stopped) { return; } #endif var hasFailed = false; var error = default(Exception); var hasValue = false; var value = default(TSource); var hasCompleted = false; var shouldWait = false; var waitTime = default(TimeSpan); lock (_gate) { if (_hasFailed) { error = _exception; hasFailed = true; } else { var now = _watch.Elapsed; if (_queue.Count > 0) { var next = _queue.Dequeue(); hasValue = true; value = next.Value; var nextDue = next.Interval; if (nextDue.CompareTo(now) > 0) { shouldWait = true; waitTime = Scheduler.Normalize(nextDue.Subtract(now)); } } else if (_hasCompleted) { hasCompleted = true; if (_completeAt.CompareTo(now) > 0) { shouldWait = true; waitTime = Scheduler.Normalize(_completeAt.Subtract(now)); } } } } /* lock (_gate) */ if (shouldWait) { #if !NO_CDS var timer = new ManualResetEventSlim(); _parent._scheduler.Schedule(waitTime, () => { timer.Set(); }); try { timer.Wait(_stop.Token); } catch (OperationCanceledException) { return; } #else var timer = new ManualResetEvent(false); _parent._scheduler.Schedule(waitTime, () => { timer.Set(); }); if (WaitHandle.WaitAny(new[] { timer, _stop }) == 1) { return; } #endif } if (hasValue) { base._observer.OnNext(value); } else { if (hasCompleted) { base._observer.OnCompleted(); base.Dispose(); } else if (hasFailed) { base._observer.OnError(error); base.Dispose(); } return; } } }
private void ReceivedSaveState(ReaderMessage.SaveState message) { this.debouncedSave = null; SaveScanState(); }
// delay action is run in StartCoroutine // Okay to action run synchronous and guaranteed run on MainThread IEnumerator DelayAction(TimeSpan dueTime, Action action, ICancelable cancellation) { #if UNITY_EDITOR if (!ScenePlaybackDetector.IsPlaying) { var startTime = DateTimeOffset.UtcNow; while (true) { yield return(null); if (cancellation.IsDisposed) { break; } var elapsed = DateTimeOffset.UtcNow - startTime; if (elapsed >= dueTime) { MainThreadDispatcher.UnsafeSend(action); break; } } ; yield break; } #endif if (dueTime == TimeSpan.Zero) { yield return(null); // not immediately, run next frame if (cancellation.IsDisposed) { yield break; } MainThreadDispatcher.UnsafeSend(action); } else if (dueTime.TotalMilliseconds % 1000 == 0) { yield return(new WaitForSeconds((float)dueTime.TotalSeconds)); if (cancellation.IsDisposed) { yield break; } MainThreadDispatcher.UnsafeSend(action); } else { var startTime = Time.time; var dt = (float)dueTime.TotalSeconds; while (true) { yield return(null); if (cancellation.IsDisposed) { break; } var elapsed = Time.time - startTime; if (elapsed >= dt) { MainThreadDispatcher.UnsafeSend(action); break; } } } }
public LiveEventsByTagPublisher(string tag, long fromOffset, long toOffset, TimeSpan refreshInterval, int maxBufferSize, string writeJournalPluginId) : base(tag, fromOffset, maxBufferSize, writeJournalPluginId) { ToOffset = toOffset; _tickCancelable = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable(refreshInterval, refreshInterval, Self, EventsByTagPublisher.Continue.Instance, Self); }
protected override bool ReceiveCommand(object message) { var match = message.Match() .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 <FSMBase.SubscribeTransitionCallBack>(cb => { Context.Watch(cb.ActorRef); Listeners.Add(cb.ActorRef); //send the current state back as a reference point cb.ActorRef.Tell(new FSMBase.CurrentState <TState>(Self, _currentState.StateName)); }) .With <Listen>(l => { Context.Watch(l.Listener); Listeners.Add(l.Listener); l.Listener.Tell(new FSMBase.CurrentState <TState>(Self, _currentState.StateName)); }) .With <FSMBase.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); }
protected abstract void InternalScheduleOnce(TimeSpan delay, Action action, ICancelable cancelable);
public CancellationToken(ICancelable source) { this.source = source; }
protected abstract void InternalScheduleTellOnce(TimeSpan delay, ICanTell receiver, object message, IActorRef sender, ICancelable cancelable);
public void ScheduleQueueing <T>(ICancelable cancel, T state, Action <T> action) { MainThreadDispatcher.StartEndOfFrameMicroCoroutine(ImmediateAction(state, action, cancel)); }
void IActionScheduler.ScheduleOnce(TimeSpan delay, Action action, ICancelable cancelable) { ValidateDelay(delay, "delay"); InternalScheduleOnce(delay, action, cancelable); }
public void ScheduleQueueing <T>(ICancelable cancel, T state, Action <T> action) { MainThreadDispatcher.Post(QueuedAction <T> .Instance, Tuple.Create(cancel, state, action)); }
void ITellScheduler.ScheduleTellOnce(TimeSpan delay, ICanTell receiver, object message, IActorRef sender, ICancelable cancelable) { ValidateDelay(delay, "delay"); InternalScheduleTellOnce(delay, receiver, message, sender, cancelable); }
/// <summary> /// TBD /// </summary> /// <param name="settings">TBD</param> /// <exception cref="ArgumentException">TBD</exception> /// <returns>TBD</returns> public DistributedPubSubMediator(DistributedPubSubSettings settings) { if (settings.RoutingLogic is ConsistentHashingRoutingLogic) { throw new ArgumentException("Consistent hashing routing logic cannot be used by the pub-sub mediator"); } _settings = settings; if (!string.IsNullOrEmpty(_settings.Role) && !_cluster.SelfRoles.Contains(_settings.Role)) { throw new ArgumentException($"The cluster member [{_cluster.SelfAddress}] doesn't have the role [{_settings.Role}]"); } //Start periodic gossip to random nodes in cluster _gossipCancelable = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable(_settings.GossipInterval, _settings.GossipInterval, Self, GossipTick.Instance, Self); _pruneInterval = new TimeSpan(_settings.RemovedTimeToLive.Ticks / 2); _pruneCancelable = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable(_pruneInterval, _pruneInterval, Self, Prune.Instance, Self); _buffer = new PerGroupingBuffer(); Receive <Send>(send => { var routees = new List <Routee>(); ValueHolder valueHolder; if (_registry.TryGetValue(_cluster.SelfAddress, out var bucket) && bucket.Content.TryGetValue(send.Path, out valueHolder) && send.LocalAffinity) { var routee = valueHolder.Routee; if (routee != null) { routees.Add(routee); } } else { foreach (var entry in _registry) { if (entry.Value.Content.TryGetValue(send.Path, out valueHolder)) { var routee = valueHolder.Routee; if (routee != null) { routees.Add(routee); } } } } if (routees.Count != 0) { new Router(_settings.RoutingLogic, routees.ToArray()).Route( Internal.Utils.WrapIfNeeded(send.Message), Sender); } else { SendToDeadLetters(send.Message); } }); Receive <SendToAll>(sendToAll => { PublishMessage(sendToAll.Path, sendToAll.Message, sendToAll.ExcludeSelf); }); Receive <Publish>(publish => { string path = Internal.Utils.MakeKey(Self.Path / Internal.Utils.EncodeName(publish.Topic)); if (publish.SendOneMessageToEachGroup) { PublishToEachGroup(path, publish.Message); } else { PublishMessage(path, publish.Message); } }); Receive <Put>(put => { if (put.Ref.Path.Address.HasGlobalScope) { Log.Warning("Registered actor must be local: [{0}]", put.Ref); } else { PutToRegistry(Internal.Utils.MakeKey(put.Ref), put.Ref); Context.Watch(put.Ref); } }); Receive <Remove>(remove => { if (_registry.TryGetValue(_cluster.SelfAddress, out var bucket)) { if (bucket.Content.TryGetValue(remove.Path, out var valueHolder) && !valueHolder.Ref.IsNobody()) { Context.Unwatch(valueHolder.Ref); PutToRegistry(remove.Path, null); } } }); Receive <Subscribe>(subscribe => { // each topic is managed by a child actor with the same name as the topic var encodedTopic = Internal.Utils.EncodeName(subscribe.Topic); _buffer.BufferOr(Internal.Utils.MakeKey(Self.Path / encodedTopic), subscribe, Sender, () => { var child = Context.Child(encodedTopic); if (!child.IsNobody()) { child.Forward(subscribe); } else { NewTopicActor(encodedTopic).Forward(subscribe); } }); }); Receive <RegisterTopic>(register => { HandleRegisterTopic(register.TopicRef); }); Receive <NoMoreSubscribers>(msg => { var key = Internal.Utils.MakeKey(Sender); _buffer.InitializeGrouping(key); Sender.Tell(TerminateRequest.Instance); }); Receive <NewSubscriberArrived>(msg => { var key = Internal.Utils.MakeKey(Sender); _buffer.ForwardMessages(key, Sender); }); Receive <GetTopics>(getTopics => { Sender.Tell(new CurrentTopics(GetCurrentTopics().ToImmutableHashSet())); }); Receive <Subscribed>(subscribed => { subscribed.Subscriber.Tell(subscribed.Ack); }); Receive <Unsubscribe>(unsubscribe => { var encodedTopic = Internal.Utils.EncodeName(unsubscribe.Topic); _buffer.BufferOr(Internal.Utils.MakeKey(Self.Path / encodedTopic), unsubscribe, Sender, () => { var child = Context.Child(encodedTopic); if (!child.IsNobody()) { child.Forward(unsubscribe); } else { // no such topic here } }); }); Receive <Unsubscribed>(unsubscribed => { unsubscribed.Subscriber.Tell(unsubscribed.Ack); }); Receive <Status>(status => { // only accept status from known nodes, otherwise old cluster with same address may interact // also accept from local for testing purposes if (_nodes.Contains(Sender.Path.Address) || Sender.Path.Address.HasLocalScope) { // gossip chat starts with a Status message, containing the bucket versions of the other node var delta = CollectDelta(status.Versions).ToArray(); if (delta.Length != 0) { Sender.Tell(new Delta(delta)); } if (!status.IsReplyToStatus && OtherHasNewerVersions(status.Versions)) { Sender.Tell(new Status(versions: OwnVersions, isReplyToStatus: true)); // it will reply with Delta } } }); Receive <Delta>(delta => { deltaCount += 1; // reply from Status message in the gossip chat // the Delta contains potential updates (newer versions) from the other node // only accept deltas/buckets from known nodes, otherwise there is a risk of // adding back entries when nodes are removed if (_nodes.Contains(Sender.Path.Address)) { foreach (var bucket in delta.Buckets) { if (_nodes.Contains(bucket.Owner)) { if (!_registry.TryGetValue(bucket.Owner, out var myBucket)) { myBucket = new Bucket(bucket.Owner); } if (bucket.Version > myBucket.Version) { _registry[bucket.Owner] = new Bucket(myBucket.Owner, bucket.Version, myBucket.Content.SetItems(bucket.Content)); } } } } }); Receive <GossipTick>(_ => HandleGossip()); Receive <Prune>(_ => HandlePrune()); Receive <Terminated>(terminated => { var key = Internal.Utils.MakeKey(terminated.ActorRef); if (_registry.TryGetValue(_cluster.SelfAddress, out var bucket)) { if (bucket.Content.TryGetValue(key, out var holder) && terminated.ActorRef.Equals(holder.Ref)) { PutToRegistry(key, null); // remove } } _buffer.RecreateAndForwardMessagesIfNeeded(key, () => NewTopicActor(terminated.ActorRef.Path.Name)); }); Receive <ClusterEvent.CurrentClusterState>(state => { var nodes = state.Members .Where(m => m.Status != MemberStatus.Joining && IsMatchingRole(m)) .Select(m => m.Address); _nodes = new HashSet <Address>(nodes); }); Receive <ClusterEvent.MemberUp>(up => { if (IsMatchingRole(up.Member)) { _nodes.Add(up.Member.Address); } }); Receive <ClusterEvent.MemberWeaklyUp>(weaklyUp => { if (IsMatchingRole(weaklyUp.Member)) { _nodes.Add(weaklyUp.Member.Address); } }); Receive <ClusterEvent.MemberLeft>(left => { if (IsMatchingRole(left.Member)) { _nodes.Remove(left.Member.Address); _registry.Remove(left.Member.Address); } }); Receive <ClusterEvent.MemberDowned>(downed => { if (IsMatchingRole(downed.Member)) { _nodes.Remove(downed.Member.Address); _registry.Remove(downed.Member.Address); } }); Receive <ClusterEvent.MemberRemoved>(removed => { var member = removed.Member; if (member.Address == _cluster.SelfAddress) { Context.Stop(Self); } else if (IsMatchingRole(member)) { _nodes.Remove(member.Address); _registry.Remove(member.Address); } }); Receive <ClusterEvent.IMemberEvent>(_ => { /* ignore */ }); Receive <Count>(_ => { var count = _registry.Sum(entry => entry.Value.Content.Count(kv => !kv.Value.Ref.IsNobody())); Sender.Tell(count); }); Receive <DeltaCount>(_ => { Sender.Tell(deltaCount); }); Receive <CountSubscribers>(msg => { var encTopic = Internal.Utils.EncodeName(msg.Topic); _buffer.BufferOr(Internal.Utils.MakeKey(Self.Path / encTopic), msg, Sender, () => { var child = Context.Child(encTopic); if (!child.IsNobody()) { child.Tell(Count.Instance, Sender); } else { Sender.Tell(0); } }); }); }
protected override void InternalScheduleTellRepeatedly(TimeSpan initialDelay, TimeSpan interval, ICanTell receiver, object message, IActorRef sender, ICancelable cancelable) { var cancellationToken = cancelable == null ? CancellationToken.None : cancelable.Token; InternalScheduleRepeatedly(initialDelay, interval, () => receiver.Tell(message, sender), cancellationToken); }
static IEnumerator DelayFrameCore(Action onNext, int frameCount, FrameCountType frameCountType, ICancelable cancel) { while (!cancel.IsDisposed && frameCount-- != 0) { yield return(frameCountType.GetYieldInstruction()); } if (!cancel.IsDisposed) { onNext(); } }
protected override void InternalScheduleOnce(TimeSpan delay, Action action, ICancelable cancelable) { var cancellationToken = cancelable == null ? CancellationToken.None : cancelable.Token; InternalScheduleOnce(delay, action, cancellationToken); }
public void ScheduleRepeatedly(TimeSpan initialDelay, TimeSpan interval, IRunnable action, ICancelable cancelable) { throw new NotImplementedException(); }