Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strange events from System.Runtime EventCounters under Linux #56695

Closed
neyromant opened this issue Aug 1, 2021 · 10 comments · Fixed by #57170
Closed

Strange events from System.Runtime EventCounters under Linux #56695

neyromant opened this issue Aug 1, 2021 · 10 comments · Fixed by #57170

Comments

@neyromant
Copy link
Contributor

neyromant commented Aug 1, 2021

Hi.
After migrating from .net 5 sdk 5.0.101 to net 5 sdk 5.0.302, I noticed strange behavior in System.Runtime EventCounters under Linux. It's about the "cpu-usage" counter. I began to receive two events in the required time interval. Moreover, in the second event, the value is clearly incorrect.

I wrote a small program to demonstrate this behavior:

using System;
using System.Collections.Generic;
using System.Diagnostics.Tracing;

namespace EventCountersProblem
{
    class Program
    {
        static void Main(string[] args)
        {
            var eventListener = new CpuTimeEventListener();
            
            Console.WriteLine("Press enter for exit");
            Console.ReadLine();
            GC.KeepAlive(eventListener);
        }
    }

    public class CpuTimeEventListener : EventListener
    {
        private readonly EventLevel _level = EventLevel.Verbose;
        
        protected override void OnEventSourceCreated(EventSource source)
        {
            if (source.Name.Equals("System.Runtime"))
            {
                var refreshInterval = new Dictionary<string, string>();
                refreshInterval.Add("EventCounterIntervalSec", "5");
                EnableEvents(source, _level, (EventKeywords)(-1), refreshInterval);
            }
        }
        protected override void OnEventWritten(EventWrittenEventArgs eventData)
        {
            if (eventData.EventName.Equals("EventCounters"))
            {
                for (int i = 0; i < eventData.Payload.Count; i++)
                {
                    IDictionary<string, object> eventPayload = eventData.Payload[i] as IDictionary<string, object>;

                    if (eventPayload != null)
                    {
                        if (eventPayload["Name"] == "cpu-usage")
                        {
                            Console.WriteLine($"{DateTime.Now}:");
                            foreach (var ep in eventPayload)
                            {
                                Console.WriteLine($"{ep.Key}: {ep.Value}");
                            }

                            Console.WriteLine("=========");
                        }
                    }
                }
            }
        }
    }
}
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

</Project>

This project is published as a self-contained application:

dotnet publish -f net5.0 -r linux-x64 -c Release

Below is the output of the program when working under Windows:

Press enter for exit
01.08.2021 15:56:44:
Name: cpu-usage
DisplayName: CPU Usage
Mean: 0
StandardDeviation: 0
Count: 1
Min: 0
Max: 0
IntervalSec: 5,0044165
Series: Interval=5000
CounterType: Mean
Metadata:
DisplayUnits: %
=========
01.08.2021 15:56:49:
Name: cpu-usage
DisplayName: CPU Usage
Mean: 0
StandardDeviation: 0
Count: 1
Min: 0
Max: 0
IntervalSec: 5,00996
Series: Interval=5000
CounterType: Mean
Metadata:
DisplayUnits: %
=========

Everything is correct here, one event every 5 seconds with the correct value.

Below is the output of the program when running under Linux Centos (CentOS Linux release 7.4.1708 (Core)):
(When run in wsl2 (ubuntu or centos), the behavior is the same)

8/1/2021 3:11:48 PM:
Name: cpu-usage
DisplayName: CPU Usage
Mean: 0
StandardDeviation: 0
Count: 1
Min: 0
Max: 0
IntervalSec: 4.9997354
Series: Interval=5000
CounterType: Mean
Metadata:
DisplayUnits: %
=========
8/1/2021 3:11:48 PM:
Name: cpu-usage
DisplayName: CPU Usage
Mean: 24
StandardDeviation: 0
Count: 1
Min: 24
Max: 24
IntervalSec: 0.0314531
Series: Interval=5000
CounterType: Mean
Metadata:
DisplayUnits: %
=========
8/1/2021 3:11:53 PM:
Name: cpu-usage
DisplayName: CPU Usage
Mean: 0
StandardDeviation: 0
Count: 1
Min: 0
Max: 0
IntervalSec: 4.968951
Series: Interval=5000
CounterType: Mean
Metadata:
DisplayUnits: %
=========
8/1/2021 3:11:53 PM:
Name: cpu-usage
DisplayName: CPU Usage
Mean: 35
StandardDeviation: 0
Count: 1
Min: 35
Max: 35
IntervalSec: 0.0021859
Series: Interval=5000
CounterType: Mean
Metadata:
DisplayUnits: %
=========

Here we see that two events are generated in a 5 second interval. In the first event, the correct value. In the second event, the value is incorrect (24% and 35% of cpu-usage).
The second event has a similarly strange meaning in IntervalSec field.

Please tell me what could be the reason for this behavior? Is this a bug? Is this related to #53836?

Thanks in advance for your reply.

p.s.
My dotnet --info output below:

Пакет SDK для .NET (отражающий любой global.json):
 Version:   6.0.100-preview.6.21355.2
 Commit:    7f8e0d76c0

Среда выполнения:
 OS Name:     Windows
 OS Version:  10.0.19043
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\6.0.100-preview.6.21355.2\

Host (useful for support):
  Version: 6.0.0-preview.6.21352.12
  Commit:  770d630b28

.NET SDKs installed:
  3.1.410 [C:\Program Files\dotnet\sdk]
  5.0.301 [C:\Program Files\dotnet\sdk]
  5.0.302 [C:\Program Files\dotnet\sdk]
  6.0.100-preview.6.21355.2 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 3.1.16 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.0-preview.6.21355.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 3.1.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.16 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.17 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.0-preview.6.21352.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.1.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 3.1.16 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 3.1.17 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 5.0.7 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 5.0.8 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.0-preview.6.21353.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

To install additional .NET runtimes or SDKs:
  https://aka.ms/dotnet-download

@dotnet-issue-labeler dotnet-issue-labeler bot added the untriaged New issue has not been triaged by the area owner label Aug 1, 2021
@dotnet-issue-labeler
Copy link

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

@ghost
Copy link

ghost commented Aug 2, 2021

Tagging subscribers to this area: @tarekgh, @tommcdon, @pjanotti
See info in area-owners.md if you want to be subscribed.

Issue Details

Hi.
After migrating from .net 5 sdk 5.0.101 to net 5 sdk 5.0.302, I noticed strange behavior in System.Runtime EventCounters under Linux. It's about the "cpu-usage" counter. I began to receive two events in the required time interval. Moreover, in the second event, the value is clearly incorrect.

I wrote a small program to demonstrate this behavior:

using System;
using System.Collections.Generic;
using System.Diagnostics.Tracing;

namespace EventCountersProblem
{
    class Program
    {
        static void Main(string[] args)
        {
            var eventListener = new CpuTimeEventListener();
            
            Console.WriteLine("Press enter for exit");
            Console.ReadLine();
            GC.KeepAlive(eventListener);
        }
    }

    public class CpuTimeEventListener : EventListener
    {
        private readonly EventLevel _level = EventLevel.Verbose;
        
        protected override void OnEventSourceCreated(EventSource source)
        {
            if (source.Name.Equals("System.Runtime"))
            {
                var refreshInterval = new Dictionary<string, string>();
                refreshInterval.Add("EventCounterIntervalSec", "5");
                EnableEvents(source, _level, (EventKeywords)(-1), refreshInterval);
            }
        }
        protected override void OnEventWritten(EventWrittenEventArgs eventData)
        {
            if (eventData.EventName.Equals("EventCounters"))
            {
                for (int i = 0; i < eventData.Payload.Count; i++)
                {
                    IDictionary<string, object> eventPayload = eventData.Payload[i] as IDictionary<string, object>;

                    if (eventPayload != null)
                    {
                        if (eventPayload["Name"] == "cpu-usage")
                        {
                            Console.WriteLine($"{DateTime.Now}:");
                            foreach (var ep in eventPayload)
                            {
                                Console.WriteLine($"{ep.Key}: {ep.Value}");
                            }

                            Console.WriteLine("=========");
                        }
                    }
                }
            }
        }
    }
}
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

</Project>

This project is published as a self-contained application:

dotnet publish -f net5.0 -r linux-x64 -c Release

Below is the output of the program when working under Windows:

Press enter for exit
01.08.2021 15:56:44:
Name: cpu-usage
DisplayName: CPU Usage
Mean: 0
StandardDeviation: 0
Count: 1
Min: 0
Max: 0
IntervalSec: 5,0044165
Series: Interval=5000
CounterType: Mean
Metadata:
DisplayUnits: %
=========
01.08.2021 15:56:49:
Name: cpu-usage
DisplayName: CPU Usage
Mean: 0
StandardDeviation: 0
Count: 1
Min: 0
Max: 0
IntervalSec: 5,00996
Series: Interval=5000
CounterType: Mean
Metadata:
DisplayUnits: %
=========

Everything is correct here, one event every 5 seconds with the correct value.

Below is the output of the program when running under Linux Centos (CentOS Linux release 7.4.1708 (Core)):
(When run in wsl2 (ubuntu or centos), the behavior is the same)

8/1/2021 3:11:48 PM:
Name: cpu-usage
DisplayName: CPU Usage
Mean: 0
StandardDeviation: 0
Count: 1
Min: 0
Max: 0
IntervalSec: 4.9997354
Series: Interval=5000
CounterType: Mean
Metadata:
DisplayUnits: %
=========
8/1/2021 3:11:48 PM:
Name: cpu-usage
DisplayName: CPU Usage
Mean: 24
StandardDeviation: 0
Count: 1
Min: 24
Max: 24
IntervalSec: 0.0314531
Series: Interval=5000
CounterType: Mean
Metadata:
DisplayUnits: %
=========
8/1/2021 3:11:53 PM:
Name: cpu-usage
DisplayName: CPU Usage
Mean: 0
StandardDeviation: 0
Count: 1
Min: 0
Max: 0
IntervalSec: 4.968951
Series: Interval=5000
CounterType: Mean
Metadata:
DisplayUnits: %
=========
8/1/2021 3:11:53 PM:
Name: cpu-usage
DisplayName: CPU Usage
Mean: 35
StandardDeviation: 0
Count: 1
Min: 35
Max: 35
IntervalSec: 0.0021859
Series: Interval=5000
CounterType: Mean
Metadata:
DisplayUnits: %
=========

Here we see that two events are generated in a 5 second interval. In the first event, the correct value. In the second event, the value is incorrect (24% and 35% of cpu-usage).
The second event has a similarly strange meaning in IntervalSec field.

Please tell me what could be the reason for this behavior? Is this a bug? Is this related to #53836?

Thanks in advance for your reply.

p.s.
My dotnet --info output below:

Пакет SDK для .NET (отражающий любой global.json):
 Version:   6.0.100-preview.6.21355.2
 Commit:    7f8e0d76c0

Среда выполнения:
 OS Name:     Windows
 OS Version:  10.0.19043
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\6.0.100-preview.6.21355.2\

Host (useful for support):
  Version: 6.0.0-preview.6.21352.12
  Commit:  770d630b28

.NET SDKs installed:
  3.1.410 [C:\Program Files\dotnet\sdk]
  5.0.301 [C:\Program Files\dotnet\sdk]
  5.0.302 [C:\Program Files\dotnet\sdk]
  6.0.100-preview.6.21355.2 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 3.1.16 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.0-preview.6.21355.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 3.1.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.16 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.17 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.0-preview.6.21352.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.1.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 3.1.16 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 3.1.17 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 5.0.7 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 5.0.8 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.0-preview.6.21353.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

To install additional .NET runtimes or SDKs:
  https://aka.ms/dotnet-download

Author: neyromant
Assignees: -
Labels:

area-System.Diagnostics.Tracing, untriaged

Milestone: -

@josalem
Copy link
Contributor

josalem commented Aug 2, 2021

Please tell me what could be the reason for this behavior? Is this a bug? Is this related to #53836?

I think your intuition is probably correct, though I'm not sure why that change would cause that behavior. On a quick glance, the new logic should be doing exactly what the old logic did and can't increment the timestamp by anything other than a multiple of the interval (due to the Math.Ceil). I'll see if this repros locally for me and try to debug through it.

@josalem josalem removed the untriaged New issue has not been triaged by the area owner label Aug 2, 2021
@josalem josalem added this to the 6.0.0 milestone Aug 2, 2021
@josalem josalem self-assigned this Aug 2, 2021
@neyromant
Copy link
Contributor Author

@josalem I also tested the work of the application built in SDK 5.0.301. No problems observed.
global.json:

{
  "sdk": {
    "version": "5.0.301"
  }
}

My test program output:

8/3/2021 11:57:15 AM:
Name: cpu-usage
DisplayName: CPU Usage
Mean: 0
StandardDeviation: 0
Count: 1
Min: 0
Max: 0
IntervalSec: 5.000747
Series: Interval=5000
CounterType: Mean
Metadata:
DisplayUnits: %
=========
8/3/2021 11:57:20 AM:
Name: cpu-usage
DisplayName: CPU Usage
Mean: 0
StandardDeviation: 0
Count: 1
Min: 0
Max: 0
IntervalSec: 4.999878
Series: Interval=5000
CounterType: Mean
Metadata:
DisplayUnits: %
=========
8/3/2021 11:57:25 AM:
Name: cpu-usage
DisplayName: CPU Usage
Mean: 0
StandardDeviation: 0
Count: 1
Min: 0
Max: 0
IntervalSec: 4.9999447
Series: Interval=5000
CounterType: Mean
Metadata:
DisplayUnits: %
=========

The problem has been observed since SDK version 5.0.302.
The problem is also present in SDK 6.0.100-preview.6.21355.2.

If necessary, I can provide more technical information about the environment or carry out the necessary checks on other SDKs.

@josalem
Copy link
Contributor

josalem commented Aug 10, 2021

I think I've worked out what happened.

The new logic:

TimeSpan delta = now - _nextPollingTimeStamp;
if (delta > TimeSpan.Zero && _pollingIntervalInMilliseconds > 0)
	_nextPollingTimeStamp += TimeSpan.FromMilliseconds(_pollingIntervalInMilliseconds * Math.Ceiling(delta.TotalMilliseconds / _pollingIntervalInMilliseconds));

can have wonky behavior if the sleep in CounterGroup.PollForValues wakes up early.

delta can be negative, which will result in _nextPollingTimeStamp not being updated. This means that sleepDurationInMilliseconds will be set to 1 and the counter will fire again on the next loop because _nextPollingTimeStamp < now + new TimeSpan.FromMilliseconds(1) will be true.

private static void PollForValues()
{
AutoResetEvent? sleepEvent = null;
// Cache of onTimer callbacks for each CounterGroup.
// We cache these outside of the scope of s_counterGroupLock because
// calling into the callbacks can cause a re-entrancy into CounterGroup.Enable()
// and result in a deadlock. (See https://github.com/dotnet/runtime/issues/40190 for details)
var onTimers = new List<CounterGroup>();
while (true)
{
int sleepDurationInMilliseconds = int.MaxValue;
lock (s_counterGroupLock)
{
sleepEvent = s_pollingThreadSleepEvent;
foreach (CounterGroup counterGroup in s_counterGroupEnabledList!)
{
DateTime now = DateTime.UtcNow;
if (counterGroup._nextPollingTimeStamp < now + new TimeSpan(0, 0, 0, 0, 1))
{
onTimers.Add(counterGroup);
}
int millisecondsTillNextPoll = (int)((counterGroup._nextPollingTimeStamp - now).TotalMilliseconds);
millisecondsTillNextPoll = Math.Max(1, millisecondsTillNextPoll);
sleepDurationInMilliseconds = Math.Min(sleepDurationInMilliseconds, millisecondsTillNextPoll);
}
}
foreach (CounterGroup onTimer in onTimers)
{
onTimer.OnTimer();
}
onTimers.Clear();
if (sleepDurationInMilliseconds == int.MaxValue)
{
sleepDurationInMilliseconds = -1; // WaitOne uses -1 to mean infinite
}
sleepEvent?.WaitOne(sleepDurationInMilliseconds);
}
}

A fix would be to switch to the following:

private const TimeSpan MinimumPollingInterval = TimeSpan.FromSeconds(1);

// ...

TimeSpan delta = now - _nextPollingTimeStamp;
delta = MinimumPollingInterval > delta ? MinimumPollingInterval : delta;
if (_pollingIntervalInMilliseconds > 0)
	_nextPollingTimeStamp += TimeSpan.FromMilliseconds(_pollingIntervalInMilliseconds * Math.Ceiling(delta.TotalMilliseconds / _pollingIntervalInMilliseconds));

The now - _nextPollingTimeStamp is calculating the difference between when the counter woke up (now) and when it was supposed to wake up (_nextPollingTimeStamp). This is supposed to then increment _nextPollingTimeStamp to the next discrete increment of _pollingIntervalInMillseconds from the origin time. This prevents the interval from sliding if counters take sufficiently long amounts of time to calculate. This updated logic without the loop, however, only increments if now > _nextPollingTimeStamp (if the counter woke up after the intended timestamp).

I need to do some more testing to be sure, but I believe this is the case. If this is true, we'll need to backport the fix to 5.0 and 3.1 since this snippet was backported all the way back.

CC @dotnet/dotnet-diag

josalem pushed a commit to josalem/runtime that referenced this issue Aug 10, 2021
* prevent a negative delta value
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Aug 10, 2021
hoyosjs pushed a commit that referenced this issue Aug 13, 2021
* Fix #56695
* prevent a negative delta value

* PR feedback + bug fix
* bug fix is preexisting: if a user other than the one who is listening sets the interval to 0 while the counter is enabled, it makes the counter continuously submit values. Changed this so that an interval value of <= 0 results in the counter being disabled

* Add assert after offline conversation
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Aug 13, 2021
@hoyosjs hoyosjs modified the milestones: 6.0.0, 5.0.x Aug 13, 2021
@hoyosjs
Copy link
Member

hoyosjs commented Aug 13, 2021

Reopening for servicing ports.

@hoyosjs hoyosjs reopened this Aug 13, 2021
@tommcdon
Copy link
Member

@hoyosjs @josalem can this issue be closed or is there a request for a backport?

@josalem
Copy link
Contributor

josalem commented Oct 19, 2021

The original issue was for .net5. It has been fixed in .net6 already. We should consider back porting it to .net5 at least.

Tomius pushed a commit to criteo-forks/runtime that referenced this issue Dec 1, 2021
* Fix dotnet#56695
* prevent a negative delta value

* PR feedback + bug fix
* bug fix is preexisting: if a user other than the one who is listening sets the interval to 0 while the counter is enabled, it makes the counter continuously submit values. Changed this so that an interval value of <= 0 results in the counter being disabled

* Add assert after offline conversation
@deeprobin
Copy link
Contributor

This has already been fixed for .NET 6 (as @josalem said). This seems to be a small change 1.
I think the /backport command would be very useful here 2.

If for some reason it doesn't work with this, I can investigate the issue in more detail.

Footnotes

  1. Diff of pull request #57170

  2. backport.yml Workflow - source

@josalem
Copy link
Contributor

josalem commented Jan 26, 2022

With support for .net5 ending in May, I'm not sure it is worth the effort to backport this change. I can be convinced otherwise, though. For now, I'll close this.

@josalem josalem closed this as completed Jan 26, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Feb 26, 2022
ezsilmar pushed a commit to criteo-forks/runtime that referenced this issue Apr 11, 2023
* Fix dotnet#56695
* prevent a negative delta value

* PR feedback + bug fix
* bug fix is preexisting: if a user other than the one who is listening sets the interval to 0 while the counter is enabled, it makes the counter continuously submit values. Changed this so that an interval value of <= 0 results in the counter being disabled

* Add assert after offline conversation
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants