private MetricsGossipEnvelope MetricsGossipEnvelopeFromProto(MetricsGossipEnvelope envelope) { var gossip = envelope.Gossip; var addressMapping = gossip.AllAddresses.Select(AddressFromProto).ToImmutableArray(); var metricNameMapping = gossip.AllMetricNames.ToImmutableArray(); Option <NodeMetrics.Types.EWMA> EwmaFromProto(NodeMetrics.Types.EWMA ewma) => new NodeMetrics.Types.EWMA(ewma.Value, ewma.Alpha); AnyNumber NumberFromProto(NodeMetrics.Types.Number number) { switch (number.Type) { case NodeMetrics.Types.NumberType.Double: return(BitConverter.Int64BitsToDouble((long)number.Value64)); case NodeMetrics.Types.NumberType.Float: return(BitConverter.ToSingle(BitConverter.GetBytes((int)number.Value32), 0)); case NodeMetrics.Types.NumberType.Integer: return(Convert.ToInt32(number.Value32)); case NodeMetrics.Types.NumberType.Long: return(Convert.ToInt64(number.Value64)); case NodeMetrics.Types.NumberType.Serialized: // TODO: Should we somehow port this? /*val in = new ClassLoaderObjectInputStream( * system.dynamicAccess.classLoader, * new ByteArrayInputStream(number.getSerialized.toByteArray)) * val obj = in.readObject * in.close() * obj.asInstanceOf[jl.Number]*/ throw new NotImplementedException($"{NodeMetrics.Types.NumberType.Serialized} number type is not supported"); default: throw new ArgumentOutOfRangeException(nameof(number)); } } NodeMetrics.Types.Metric MetricFromProto(NodeMetrics.Types.Metric metric) { return(new NodeMetrics.Types.Metric( metricNameMapping[metric.NameIndex], NumberFromProto(metric.Number), metric.Ewma != null ? EwmaFromProto(metric.Ewma) : Option <NodeMetrics.Types.EWMA> .None)); } NodeMetrics NodeMetricsFromProto(NodeMetrics metrics) { return(new NodeMetrics( addressMapping[metrics.AddressIndex], metrics.Timestamp, metrics.Metrics.Select(MetricFromProto).ToImmutableArray())); } var nodeMetrics = gossip.NodeMetrics.Select(NodeMetricsFromProto).ToImmutableHashSet(); return(new MetricsGossipEnvelope(AddressFromProto(envelope.From), new MetricsGossip(nodeMetrics), envelope.Reply)); }
private MetricsGossipEnvelope MetricsGossipEnvelopeToProto(MetricsGossipEnvelope envelope) { var allNodeMetrics = envelope.Gossip.Nodes; var allAddresses = allNodeMetrics.Select(m => m.Address).ToImmutableArray(); var addressMapping = allAddresses.Select((a, i) => (Index: i, Value: a)).ToImmutableDictionary(p => p.Value, p => p.Index); var allMetricNames = allNodeMetrics.Aggregate( ImmutableHashSet <string> .Empty, (set, metrics) => set.Union(metrics.Metrics.Select(m => m.Name))).ToImmutableArray(); var metricNamesMapping = allMetricNames.Select((a, i) => (Index: i, Value: a)).ToImmutableDictionary(p => p.Value, p => p.Index); int MapAddress(Actor.Address address) => MapWithErrorMessage(addressMapping, address, "address"); int MapName(string name) => MapWithErrorMessage(metricNamesMapping, name, "metric name"); Option <NodeMetrics.Types.EWMA> EwmaToProto(Option <NodeMetrics.Types.EWMA> ewma) => ewma.Select(e => new NodeMetrics.Types.EWMA(e.Value, e.Alpha)); NodeMetrics.Types.Number NumberToProto(AnyNumber number) { var proto = new NodeMetrics.Types.Number(); switch (number.Type) { case AnyNumber.NumberType.Int: proto.Type = NodeMetrics.Types.NumberType.Integer; proto.Value32 = Convert.ToUInt32(number.LongValue); break; case AnyNumber.NumberType.Long: proto.Type = NodeMetrics.Types.NumberType.Long; proto.Value64 = Convert.ToUInt64(number.LongValue); break; case AnyNumber.NumberType.Float: proto.Type = NodeMetrics.Types.NumberType.Float; proto.Value32 = (uint)BitConverter.ToInt32(BitConverter.GetBytes((float)number.DoubleValue), 0); break; case AnyNumber.NumberType.Double: proto.Type = NodeMetrics.Types.NumberType.Double; proto.Value64 = (ulong)BitConverter.DoubleToInt64Bits(number.DoubleValue); break; default: throw new ArgumentOutOfRangeException(); } return(proto); } NodeMetrics.Types.Metric MetricToProto(NodeMetrics.Types.Metric m) { var metric = new NodeMetrics.Types.Metric() { NameIndex = MapName(m.Name), Number = NumberToProto(m.Value), }; var ewma = EwmaToProto(m.Average); if (ewma.HasValue) { metric.Ewma = ewma.Value; } return(metric); } NodeMetrics NodeMetricsToProto(NodeMetrics nodeMetrics) { return(new NodeMetrics() { AddressIndex = MapAddress(nodeMetrics.Address), Timestamp = nodeMetrics.Timestamp, Metrics = { nodeMetrics.Metrics.Select(MetricToProto) } }); } var nodeMetricsProto = allNodeMetrics.Select(NodeMetricsToProto); return(new MetricsGossipEnvelope() { From = AddressToProto(envelope.FromAddress), Reply = envelope.Reply, Gossip = new MetricsGossip() { AllAddresses = { allAddresses.Select(AddressToProto) }, AllMetricNames = { allMetricNames }, NodeMetrics = { nodeMetricsProto } } }); }