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 }
public ClusterMetricsCollector(ActorRef publisher) { _publisher = publisher; _cluster = Cluster.Get(Context.System); Collector = MetricsCollector.Get(Context.System.AsInstanceOf <ExtendedActorSystem>(), _cluster.Settings); LatestGossip = MetricsGossip.Empty; Nodes = ImmutableHashSet.Create <Address>(); _metricsTask = new CancellationTokenSource(); Context.System.Scheduler.Schedule(_cluster.Settings.PeriodicTasksInitialDelay.Max(_cluster.Settings.MetricsInterval), _cluster.Settings.MetricsInterval, Self, InternalClusterAction.MetricsTick.Instance, _metricsTask.Token); _gossipTask = new CancellationTokenSource(); Context.System.Scheduler.Schedule(_cluster.Settings.PeriodicTasksInitialDelay.Max(_cluster.Settings.GossipInterval), _cluster.Settings.GossipInterval, Self, InternalClusterAction.GossipTick.Instance, _gossipTask.Token); 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 }
/// <summary> /// Receives changes from peer nodes, merges remote with local gossip nodes, then publishes /// changes to the event stream for load balancing router consumption, and gossip back. /// </summary> private void ReceiveGossip(MetricsGossipEnvelope envelope) { // remote node might not have same view of member nodes, this side should only care // about nodes that are known here, otherwise removed nodes can come back var otherGossip = envelope.Gossip.Filter(Nodes); LatestGossip = LatestGossip.Merge(otherGossip); // changes will be published in the period collect task if (!envelope.Reply) { ReplyGossipTo(envelope.From); } }
public MetricsGossipEnvelope(Address @from, MetricsGossip gossip, bool reply) { Reply = reply; Gossip = gossip; From = @from; }
private bool Equals(MetricsGossip other) { return Nodes.SequenceEqual(other.Nodes); }
/// <summary> /// Adds new remote <see cref="NodeMetrics"/> and merges existing from a remote gossip. /// </summary> public MetricsGossip Merge(MetricsGossip otherGossip) { return otherGossip.Nodes.Aggregate(this, (gossip, metrics) => gossip + metrics); }
/// <summary> /// Receives changes from peer nodes, merges remote with local gossip nodes, then publishes /// changes to the event stream for load balancing router consumption, and gossip back. /// </summary> private void ReceiveGossip(MetricsGossipEnvelope envelope) { // remote node might not have same view of member nodes, this side should only care // about nodes that are known here, otherwise removed nodes can come back var otherGossip = envelope.Gossip.Filter(Nodes); LatestGossip = LatestGossip.Merge(otherGossip); // changes will be published in the period collect task if (!envelope.Reply) ReplyGossipTo(envelope.From); }
/// <summary> /// Samples the latest metrics for the node, updates metrics statistics in <see cref="MetricsGossip"/>, and /// publishes the changes to the event bus. /// </summary> private void Collect() { LatestGossip = LatestGossip + Collector.Sample(); Publish(); }
/// <summary> /// Removes a member from the node ring. /// </summary> private void RemoveMember(Member member) { Nodes = Nodes.Remove(member.Address); LatestGossip = LatestGossip.Remove(member.Address); }
private bool Equals(MetricsGossip other) { return(Nodes.SequenceEqual(other.Nodes)); }
/// <summary> /// Adds new remote <see cref="NodeMetrics"/> and merges existing from a remote gossip. /// </summary> public MetricsGossip Merge(MetricsGossip otherGossip) { return(otherGossip.Nodes.Aggregate(this, (gossip, metrics) => gossip + metrics)); }