- 
                Notifications
    You must be signed in to change notification settings 
- Fork 5.2k
Closed
Labels
api-suggestionEarly API idea and discussion, it is NOT ready for implementationEarly API idea and discussion, it is NOT ready for implementationarea-System.Diagnostics.MetricenhancementProduct code improvement that does NOT require public API changes/additionsProduct code improvement that does NOT require public API changes/additions
Milestone
Description
Background and motivation
InstrumentRecorder is an API new in .NET 8 to make testing metrics easier:
var instrumentRecorder = new InstrumentRecorder<double>(meterRegistry, "Microsoft.AspNetCore.Hosting", "request-duration"); 
var response = await httpClient.GetAsync("/");
var measurements = instrumentRecorder.GetMeasurements();
// Assert contents of measurementsHowever, there are some cases where there are race conditions because measurements happen on a different thread. For example, with the request-duration counter above, the server can return the failing response to the client before the metric is recorded. GetMeasurements may or may not have an item. The test is flaky.
It would be useful if someone using InstrumentRecorder could get notifications of new measurements.
API Proposal
namespace System.Diaganostics.Metrics;
public class InstumentRecorder<T>
{
    // Wait for any number of measurements.
    public Task<IEnumerable<Measurement<T>> WaitForMeasurementsAsync(bool clear = false)
        => WaitForMeasurementsAsync(minimumCount: 1, clear);
    // Wait for measurements greater than count.
    public Task<IEnumerable<Measurement<T>> WaitForMeasurementsAsync(int minimumCount, bool clear = false);
}WaitForMeasurementsAsync returns when one or more measurements are available. If there are already measurements, the method returns immediately.
Random thoughts:
- It might be worth having a count overload on the method, allowing someone to wait for an expected number of measurements, e.g. WaitForMeasurementsAsync(minimumCount: 5). Edit: Added above.
- Are parallel calls to WaitForMeasurementsAsyncallowed? What happens if there are parallel calls toWaitForMeasurementsAsync, and they haveclear: true?
- If someone wants to wait multiple times, they must clear the measurements (or increase the wait count). The example below shows this.
API Usage
var instrumentRecorder = new InstrumentRecorder<double>(meterRegistry, "Microsoft.AspNetCore.Hosting", "request-duration"); 
var response1 = await httpClient.GetAsync("/");
var measurements1 = await instrumentRecorder.WaitForMeasurementsAsync(clear: true);
// Assert contents of measurements
var response2 = await httpClient.GetAsync("/");
var measurements2 = await instrumentRecorder.WaitForMeasurementsAsync(clear: true);
// Assert contents of measurementsAlternative Designs
An API to register a callback that executes for each measurement:
var tcs = new TaskCompletionSource();
var instrumentRecorder = new InstrumentRecorder<double>(meterRegistry, "Microsoft.AspNetCore.Hosting", "request-duration"); 
instrumentRecorder.Register(m => 
{ 
    tcs.TrySetResult(); 
});
// Do stuff
await tcs.Task;
var measurements = await instrumentRecorder.GetMeasurements();
// Assert contents of measurementsRisks
No response
Metadata
Metadata
Assignees
Labels
api-suggestionEarly API idea and discussion, it is NOT ready for implementationEarly API idea and discussion, it is NOT ready for implementationarea-System.Diagnostics.MetricenhancementProduct code improvement that does NOT require public API changes/additionsProduct code improvement that does NOT require public API changes/additions