public void MultithreadedLongCounterTest() { var exportedItems = new List <Metric>(); using var meter = new Meter(Utils.GetCurrentMethodName()); var counterLong = meter.CreateCounter <long>("mycounter"); using var meterProvider = Sdk.CreateMeterProviderBuilder() .AddMeter(meter.Name) .AddReader(new BaseExportingMetricReader(new InMemoryExporter <Metric>(exportedItems)) { Temporality = AggregationTemporality.Cumulative, }) .Build(); // setup args to threads. var mreToBlockUpdateThreads = new ManualResetEvent(false); var mreToEnsureAllThreadsStarted = new ManualResetEvent(false); var argToThread = new UpdateThreadArguments <long>(); argToThread.DeltaValueUpdatedByEachCall = deltaLongValueUpdatedByEachCall; argToThread.Counter = counterLong; argToThread.ThreadsStartedCount = 0; argToThread.MreToBlockUpdateThread = mreToBlockUpdateThreads; argToThread.MreToEnsureAllThreadsStart = mreToEnsureAllThreadsStarted; Thread[] t = new Thread[numberOfThreads]; for (int i = 0; i < numberOfThreads; i++) { t[i] = new Thread(CounterUpdateThread <long>); t[i].Start(argToThread); } // Block until all threads started. mreToEnsureAllThreadsStarted.WaitOne(); Stopwatch sw = Stopwatch.StartNew(); // unblock all the threads. // (i.e let them start counter.Add) mreToBlockUpdateThreads.Set(); for (int i = 0; i < numberOfThreads; i++) { // wait for all threads to complete t[i].Join(); } var timeTakenInMilliseconds = sw.ElapsedMilliseconds; this.output.WriteLine($"Took {timeTakenInMilliseconds} msecs. Total threads: {numberOfThreads}, each thread doing {numberOfMetricUpdateByEachThread} recordings."); meterProvider.ForceFlush(MaxTimeToAllowForFlush); var sumReceived = GetLongSum(exportedItems); var expectedSum = deltaLongValueUpdatedByEachCall * numberOfMetricUpdateByEachThread * numberOfThreads; Assert.Equal(expectedSum, sumReceived); }
public void MeasureAggregatorAggregatesCorrectlyWhenMultipleThreadsUpdatesDouble() { // create an aggregator var aggregator = new DoubleMeasureMinMaxSumCountAggregator(); var summary = aggregator.ToMetricData() as SummaryData <double>; // we start with 0. Assert.Equal(0, summary.Sum); Assert.Equal(0, summary.Count); // setup args to threads. var mre = new ManualResetEvent(false); var mreToEnsureAllThreadsStart = new ManualResetEvent(false); var argToThread = new UpdateThreadArguments <double> { minMaxSumCountAggregator = aggregator, threadsStartedCount = 0, mreToBlockUpdateThread = mre, mreToEnsureAllThreadsStart = mreToEnsureAllThreadsStart }; Thread[] t = new Thread[10]; for (int i = 0; i < 10; i++) { t[i] = new Thread(DoubleMetricUpdateThread); t[i].Start(argToThread); } // Block until all 10 threads started. mreToEnsureAllThreadsStart.WaitOne(); // kick-off all the threads. mre.Set(); for (int i = 0; i < 10; i++) { // wait for all threads to complete t[i].Join(); } // check point. aggregator.Checkpoint(); summary = aggregator.ToMetricData() as SummaryData <double>; // 1000000 times (10+50+100) by each thread. times 10 as there are 10 threads Assert.Equal(1600000000, summary.Sum); // 1000000 times 3 by each thread, times 10 as there are 10 threads. Assert.Equal(30000000, summary.Count); // Min and Max are 10 and 100 Assert.Equal(10, summary.Min); Assert.Equal(100, summary.Max); }
private void MultithreadedCounterTest <T>(T deltaValueUpdatedByEachCall) where T : struct, IComparable { var metricItems = new List <Metric>(); var metricReader = new BaseExportingMetricReader(new InMemoryExporter <Metric>(metricItems)); using var meter = new Meter($"{Utils.GetCurrentMethodName()}.{typeof(T).Name}.{deltaValueUpdatedByEachCall}"); using var meterProvider = Sdk.CreateMeterProviderBuilder() .AddMeter(meter.Name) .AddReader(metricReader) .Build(); var argToThread = new UpdateThreadArguments <T> { ValuesToRecord = new T[] { deltaValueUpdatedByEachCall }, Instrument = meter.CreateCounter <T>("counter"), MreToBlockUpdateThread = new ManualResetEvent(false), MreToEnsureAllThreadsStart = new ManualResetEvent(false), }; Thread[] t = new Thread[numberOfThreads]; for (int i = 0; i < numberOfThreads; i++) { t[i] = new Thread(CounterUpdateThread <T>); t[i].Start(argToThread); } argToThread.MreToEnsureAllThreadsStart.WaitOne(); Stopwatch sw = Stopwatch.StartNew(); argToThread.MreToBlockUpdateThread.Set(); for (int i = 0; i < numberOfThreads; i++) { t[i].Join(); } this.output.WriteLine($"Took {sw.ElapsedMilliseconds} msecs. Total threads: {numberOfThreads}, each thread doing {numberOfMetricUpdateByEachThread} recordings."); metricReader.Collect(); if (typeof(T) == typeof(long)) { var sumReceived = GetLongSum(metricItems); var expectedSum = deltaLongValueUpdatedByEachCall * numberOfMetricUpdateByEachThread * numberOfThreads; Assert.Equal(expectedSum, sumReceived); } else if (typeof(T) == typeof(double)) { var sumReceived = GetDoubleSum(metricItems); var expectedSum = deltaDoubleValueUpdatedByEachCall * numberOfMetricUpdateByEachThread * numberOfThreads; Assert.Equal(expectedSum, sumReceived, 2); } }
private void MultithreadedHistogramTest <T>(long[] expected, T[] values) where T : struct, IComparable { var bucketCounts = new long[11]; var metricReader = new BaseExportingMetricReader(new TestExporter <Metric>(batch => { foreach (var metric in batch) { foreach (var metricPoint in metric.GetMetricPoints()) { bucketCounts = metricPoint.GetHistogramBuckets().RunningBucketCounts; } } })); using var meter = new Meter($"{Utils.GetCurrentMethodName()}.{typeof(T).Name}"); using var meterProvider = Sdk.CreateMeterProviderBuilder() .AddMeter(meter.Name) .AddReader(metricReader) .Build(); var argsToThread = new UpdateThreadArguments <T> { Instrument = meter.CreateHistogram <T>("histogram"), MreToBlockUpdateThread = new ManualResetEvent(false), MreToEnsureAllThreadsStart = new ManualResetEvent(false), ValuesToRecord = values, }; Thread[] t = new Thread[numberOfThreads]; for (int i = 0; i < numberOfThreads; i++) { t[i] = new Thread(HistogramUpdateThread <T>); t[i].Start(argsToThread); } argsToThread.MreToEnsureAllThreadsStart.WaitOne(); Stopwatch sw = Stopwatch.StartNew(); argsToThread.MreToBlockUpdateThread.Set(); for (int i = 0; i < numberOfThreads; i++) { t[i].Join(); } this.output.WriteLine($"Took {sw.ElapsedMilliseconds} msecs. Total threads: {numberOfThreads}, each thread doing {numberOfMetricUpdateByEachThread * values.Length} recordings."); metricReader.Collect(); Assert.Equal(expected, bucketCounts); }
public void CounterAggregatorAggregatesCorrectlyWhenMultipleThreadsUpdatesDouble() { // create an aggregator var aggregator = new DoubleCounterSumAggregator(); var sum = aggregator.ToMetricData() as DoubleSumData; // we start with 0.0 Assert.Equal(0.0, sum.Sum); // setup args to threads. var mre = new ManualResetEvent(false); var mreToEnsureAllThreadsStart = new ManualResetEvent(false); var argToThread = new UpdateThreadArguments <double> { CounterSumAggregator = aggregator, ThreadsStartedCount = 0, MreToBlockUpdateThread = mre, MreToEnsureAllThreadsStart = mreToEnsureAllThreadsStart, }; Thread[] t = new Thread[10]; for (int i = 0; i < 10; i++) { t[i] = new Thread(DoubleMetricUpdateThread); t[i].Start(argToThread); } // Block until all 10 threads started. mreToEnsureAllThreadsStart.WaitOne(); // kick-off all the threads. mre.Set(); for (int i = 0; i < 10; i++) { // wait for all threads to complete t[i].Join(); } // check point. aggregator.Checkpoint(); sum = aggregator.ToMetricData() as DoubleSumData; // 1000000 times 10.5 by each thread. times 10 as there are 10 threads Assert.Equal(105000000, sum.Sum); }
public void CounterAggregatorAggregatesCorrectlyWhenMultipleThreadsUpdatesLong() { // create an aggregator CounterSumAggregator <long> aggregator = new CounterSumAggregator <long>(); var sum = aggregator.ValueFromLastCheckpoint(); // we start with 0. Assert.Equal(0, sum); // setup args to threads. var mre = new ManualResetEvent(false); var mreToEnsureAllThreadsStart = new ManualResetEvent(false); var argToThread = new UpdateThreadArguments <long>(); argToThread.counterSumAggregator = aggregator; argToThread.threadsStartedCount = 0; argToThread.mreToBlockUpdateThread = mre; argToThread.mreToEnsureAllThreadsStart = mreToEnsureAllThreadsStart; Thread[] t = new Thread[10]; for (int i = 0; i < 10; i++) { t[i] = new Thread(LongMetricUpdateThread); t[i].Start(argToThread); } // Block until all 10 threads started. mreToEnsureAllThreadsStart.WaitOne(); // kick-off all the threads. mre.Set(); for (int i = 0; i < 10; i++) { // wait for all threads to complete t[i].Join(); } // check point. aggregator.Checkpoint(); sum = aggregator.ValueFromLastCheckpoint(); // 1000000 times 10 by each thread. times 10 as there are 10 threads Assert.Equal(100000000, sum); }
public void MultithreadedDoubleCounterTest() { var metricItems = new List <Metric>(); var metricExporter = new TestExporter <Metric>(ProcessExport); void ProcessExport(Batch <Metric> batch) { foreach (var metricItem in batch) { metricItems.Add(metricItem); } } var metricReader = new BaseExportingMetricReader(metricExporter) { PreferredAggregationTemporality = AggregationTemporality.Cumulative, }; using var meter = new Meter("TestDoubleCounterMeter"); var counterDouble = meter.CreateCounter <double>("mycounter"); using var meterProvider = Sdk.CreateMeterProviderBuilder() .AddMeter("TestDoubleCounterMeter") .AddReader(metricReader) .Build(); // setup args to threads. var mreToBlockUpdateThreads = new ManualResetEvent(false); var mreToEnsureAllThreadsStarted = new ManualResetEvent(false); var argToThread = new UpdateThreadArguments <double>(); argToThread.DeltaValueUpdatedByEachCall = deltaDoubleValueUpdatedByEachCall; argToThread.Counter = counterDouble; argToThread.ThreadsStartedCount = 0; argToThread.MreToBlockUpdateThread = mreToBlockUpdateThreads; argToThread.MreToEnsureAllThreadsStart = mreToEnsureAllThreadsStarted; Thread[] t = new Thread[numberOfThreads]; for (int i = 0; i < numberOfThreads; i++) { t[i] = new Thread(CounterUpdateThread <double>); t[i].Start(argToThread); } // Block until all threads started. mreToEnsureAllThreadsStarted.WaitOne(); Stopwatch sw = Stopwatch.StartNew(); // unblock all the threads. // (i.e let them start counter.Add) mreToBlockUpdateThreads.Set(); for (int i = 0; i < numberOfThreads; i++) { // wait for all threads to complete t[i].Join(); } var timeTakenInMilliseconds = sw.ElapsedMilliseconds; this.output.WriteLine($"Took {timeTakenInMilliseconds} msecs. Total threads: {numberOfThreads}, each thread doing {numberOfMetricUpdateByEachThread} recordings."); metricReader.Collect(); var sumReceived = GetDoubleSum(metricItems); var expectedSum = deltaDoubleValueUpdatedByEachCall * numberOfMetricUpdateByEachThread * numberOfThreads; var difference = Math.Abs(sumReceived - expectedSum); Assert.True(difference <= 0.0001); }
public void SimpleTest() { var metricItems = new List <MetricItem>(); var metricExporter = new TestExporter <MetricItem>(ProcessExport); void ProcessExport(Batch <MetricItem> batch) { foreach (var metricItem in batch) { metricItems.Add(metricItem); } } var pullProcessor = new PullMetricProcessor(metricExporter, true); var meter = new Meter("TestMeter"); var counterLong = meter.CreateCounter <long>("mycounter"); var meterProvider = Sdk.CreateMeterProviderBuilder() .AddSource("TestMeter") .AddMetricProcessor(pullProcessor) .Build(); // setup args to threads. var mreToBlockUpdateThreads = new ManualResetEvent(false); var mreToEnsureAllThreadsStarted = new ManualResetEvent(false); var argToThread = new UpdateThreadArguments(); argToThread.Counter = counterLong; argToThread.ThreadsStartedCount = 0; argToThread.MreToBlockUpdateThread = mreToBlockUpdateThreads; argToThread.MreToEnsureAllThreadsStart = mreToEnsureAllThreadsStarted; Thread[] t = new Thread[numberOfThreads]; for (int i = 0; i < numberOfThreads; i++) { t[i] = new Thread(CounterUpdateThread); t[i].Start(argToThread); } // Block until all threads started. mreToEnsureAllThreadsStarted.WaitOne(); Stopwatch sw = new Stopwatch(); sw.Start(); // unblock all the threads. // (i.e let them start counter.Add) mreToBlockUpdateThreads.Set(); for (int i = 0; i < numberOfThreads; i++) { // wait for all threads to complete t[i].Join(); } var timeTakenInMilliseconds = sw.ElapsedMilliseconds; this.output.WriteLine($"Took {timeTakenInMilliseconds} msecs. Total threads: {numberOfThreads}, each thread doing {numberOfMetricUpdateByEachThread} recordings."); meterProvider.Dispose(); pullProcessor.PullRequest(); long sumReceived = 0; foreach (var metricItem in metricItems) { var metrics = metricItem.Metrics; foreach (var metric in metrics) { sumReceived += (metric as ISumMetricLong).LongSum; } } var expectedSum = deltaValueUpdatedByEachCall * numberOfMetricUpdateByEachThread * numberOfThreads; Assert.Equal(expectedSum, sumReceived); }