0

I'm trying to dynamically report the load against all the instances of my stateless service. The goal is to read the reported values from the code later on. So far I have the code to report some metrics and read them with FabricClient, but the numbers I get are always 0 no matter what I do. So here is how service is configured -

<StatelessService ServiceTypeName="MySvcType" InstanceCount="-1">
    <SingletonPartition />
    <LoadMetrics>
      <LoadMetric Name="MemoryInMb" />
      <LoadMetric Name="CPU" />
    </LoadMetrics>
</StatelessService>

The code that reports the metrics -

    protected override async Task RunAsync(CancellationToken cancellationToken)
    {
        await base.RunAsync(cancellationToken);

        PerformanceCounter cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
        PerformanceCounter ramCounter = new PerformanceCounter("Memory", "Available MBytes");

        while (true)
        {
            cancellationToken.ThrowIfCancellationRequested();

            this.Partition.ReportLoad(new List<LoadMetric> { new LoadMetric("MemoryInMb", (int)ramCounter.NextValue()), new LoadMetric("CPU", (int)cpuCounter.NextValue()) });

            await Task.Delay(5000);
        }
    }

And here is the code I have to pull out those metrics -

        var partitions = await fabricClient.QueryManager.GetPartitionListAsync(new Uri("fabric:/MyApp/MySvc"));
        foreach (var partition in partitions)
        {
            var partitionLoad = await fabricClient.QueryManager.GetPartitionLoadInformationAsync(partition.PartitionInformation.Id);

            var replicas = new List<Replica>();
            ServiceReplicaList replicaList = await fabricClient.QueryManager.GetReplicaListAsync(partition.PartitionInformation.Id);
            replicas.AddRange(replicaList);
            while (!string.IsNullOrEmpty(replicaList.ContinuationToken))
            {
                replicaList = await fabricClient.QueryManager.GetReplicaListAsync(partition.PartitionInformation.Id, replicaList.ContinuationToken);
                replicas.AddRange(replicaList);
            }

            foreach(var replica in replicas)
            {
                var replicaLoad = await fabricClient.QueryManager.GetReplicaLoadInformationAsync(partition.PartitionInformation.Id, replica.Id);
                var memoryReports = replicaLoad.LoadMetricReports.Where(r => r.Name == "MemoryInMb");
                var cpuReports = replicaLoad.LoadMetricReports.Where(r => r.Name == "CPU");
            }
        }

So I get back only one report per each metric I've defined and value is always 0. Any thoughts on what should I do to start retrieving the values that are reported in my stateless service?

Kiryl
  • 1,416
  • 9
  • 21

1 Answers1

2

Load metrics are buffered and sent to the cluster every five minutes. Maybe you're just not waiting long enough?

Vaclav Turecek
  • 9,020
  • 24
  • 29
  • Turns out you are right. Nice! Do I have means to alter this period? – Kiryl Mar 21 '17 at 19:29
  • 1
    Never mind. Seems like I've figured the way to alter the interval at https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-cluster-resource-manager-balancing. – Kiryl Mar 22 '17 at 12:58
  • 1
    Update - the previous link doesn't lead to the solution. Here is a correct one - http://stackoverflow.com/questions/36472459/service-fabric-resource-balancer-uses-stale-reported-load. – Kiryl Mar 25 '17 at 14:16