示例#1
0
        /// <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.Select(n => n).ToImmutableHashSet());

            _latestGossip = _latestGossip.Merge(otherGossip);

            // changes will be published in the period collect task
            if (!envelope.Reply)
            {
                ReplyGossipTo(envelope.FromAddress);
            }
        }
示例#2
0
        private Msg.MetricsGossipEnvelope MetricsGossipEnvelopeToProto(MetricsGossipEnvelope envelope)
        {
            var mgossip        = envelope.Gossip;
            var allAddresses   = mgossip.Nodes.Select(x => x.Address).ToList();
            var addressMapping = allAddresses.ZipWithIndex();
            var allMetricNames = mgossip.Nodes.Aggregate(ImmutableHashSet.Create <string>(),
                                                         (set, metrics) => set = set.Union(metrics.Metrics.Select(x => x.Name)));
            var metricNamesMapping = allMetricNames.ZipWithIndex();

            Func <Address, int> mapAddress = address => MapWithErrorMessage(addressMapping, address, "address");
            Func <string, int>  mapName    = name => MapWithErrorMessage(metricNamesMapping, name, "address");

            Func <EWMA, Msg.NodeMetrics.Types.EWMA.Builder> ewmaToProto = ewma => ewma == null ? null :
                                                                          Msg.NodeMetrics.Types.EWMA.CreateBuilder().SetAlpha(ewma.Alpha).SetValue(ewma.Value);

            // we set all metric types as doubles, since we don't have a convenient Number base class like Scala
            Func <double, Msg.NodeMetrics.Types.Number.Builder> numberToProto = d => Msg.NodeMetrics.Types.Number.CreateBuilder()
                                                                                .SetType(Msg.NodeMetrics.Types.NumberType.Double)
                                                                                .SetValue64((ulong)BitConverter.DoubleToInt64Bits(d));

            Func <Metric, Msg.NodeMetrics.Types.Metric.Builder> metricToProto = metric =>
            {
                var builder =
                    Msg.NodeMetrics.Types.Metric.CreateBuilder()
                    .SetNameIndex(mapName(metric.Name))
                    .SetNumber(numberToProto(metric.Value));
                var ewmaBuilder = ewmaToProto(metric.Average);
                return(ewmaBuilder != null?builder.SetEwma(ewmaBuilder) : builder);
            };

            Func <NodeMetrics, Msg.NodeMetrics.Builder> nodeMetricsToProto = metrics => Msg.NodeMetrics.CreateBuilder()
                                                                             .SetAddressIndex(mapAddress(metrics.Address))
                                                                             .SetTimestamp(metrics.Timestamp)
                                                                             .AddRangeMetrics(metrics.Metrics.Select(x => metricToProto(x).Build()));

            var nodeMetrics = mgossip.Nodes.Select(x => nodeMetricsToProto(x).Build());

            return(Msg.MetricsGossipEnvelope.CreateBuilder().SetFrom(AddressToProto(envelope.From)).SetGossip(
                       Msg.MetricsGossip.CreateBuilder()
                       .AddRangeAllAddresses(allAddresses.Select(x => AddressToProto(x).Build()))
                       .AddRangeAllMetricNames(allMetricNames).AddRangeNodeMetrics(nodeMetrics))
                   .SetReply(envelope.Reply)
                   .Build());
        }
示例#3
0
 private void SendGossip(Akka.Actor.Address address, MetricsGossipEnvelope envelope)
 {
     Context.ActorSelection(Self.Path.ToStringWithAddress(address)).Tell(envelope);
 }