Skip to content

Commit 1db780d

Browse files
authored
Merge pull request #7 from prom-client-net/feat/default-interval
feat: add default interval
2 parents b746499 + 3e6754b commit 1db780d

8 files changed

+111
-56
lines changed

.ruleset

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@
130130
<Rule Id="SA1400" Action="None" />
131131
<Rule Id="SA1401" Action="None" />
132132
<Rule Id="SA1119" Action="None" />
133+
<Rule Id="SA1407" Action="None" />
133134
<Rule Id="SA1410" Action="None" />
134135
<Rule Id="SA1411" Action="None" />
135136
<Rule Id="SA1404" Action="None" />

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ var metricPusher = new MetricPusher(new MetricPusherOptions
2929
```
3030

3131
```c#
32-
services.AddMetricPusherService(metricPusher, TimeSpan.FromSeconds(1));
32+
services.AddMetricPusherService(metricPusher);
3333
```
3434

3535
## Contribute

src/Defaults.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
using System;
2+
3+
namespace Prometheus.Client.MetricPusher.HostedService;
4+
5+
internal static class Defaults
6+
{
7+
internal static TimeSpan Interval = TimeSpan.FromMilliseconds(1000);
8+
}

src/MetricPusherService.cs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,39 +10,45 @@ public class MetricPusherService : BackgroundService
1010
private readonly IMetricPusher _pusher;
1111
private readonly TimeSpan _interval;
1212

13+
public MetricPusherService(IMetricPusher pusher)
14+
: this(pusher, Defaults.Interval)
15+
{
16+
}
17+
1318
public MetricPusherService(IMetricPusher pusher, TimeSpan interval)
1419
{
15-
_interval = interval;
1620
_pusher = pusher;
21+
_interval = interval;
1722
}
1823

1924
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
2025
{
21-
async Task DoPushAsync()
26+
while (!stoppingToken.IsCancellationRequested)
2227
{
28+
await DoPushAsync();
2329
try
2430
{
25-
await _pusher.PushAsync();
31+
await Task.Delay(_interval, stoppingToken);
2632
}
27-
catch (Exception)
33+
catch (TaskCanceledException)
2834
{
29-
// TODO: report error to DiagnosticSource?
3035
}
3136
}
3237

33-
while (!stoppingToken.IsCancellationRequested)
38+
// Push the very last metric values before exit
39+
await DoPushAsync();
40+
return;
41+
42+
async Task DoPushAsync()
3443
{
35-
await DoPushAsync();
3644
try
3745
{
38-
await Task.Delay(_interval, stoppingToken);
46+
await _pusher.PushAsync();
3947
}
40-
catch (TaskCanceledException)
48+
catch (Exception)
4149
{
50+
// TODO: report error to DiagnosticSource?
4251
}
4352
}
44-
45-
// Push the very last metric values before exit
46-
await DoPushAsync();
4753
}
4854
}

src/Prometheus.Client.MetricPusher.HostedService.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<TargetFrameworks>netstandard2.1;net6.0;net7.0</TargetFrameworks>
4-
<VersionPrefix>0.1.0</VersionPrefix>
4+
<VersionPrefix>0.2.0</VersionPrefix>
55
<Description>Prometheus.Client.MetricPusher as HostedService</Description>
66
<RepositoryUrl>https://github.com/prom-client-net/prom-client-metricpusher-hostedservice</RepositoryUrl>
77
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>

src/ServiceCollectionExtensions.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ namespace Prometheus.Client.MetricPusher.HostedService;
66

77
public static class ServiceCollectionExtensions
88
{
9+
public static IServiceCollection AddMetricPusherService(this IServiceCollection services, IMetricPusher pusher)
10+
{
11+
return AddMetricPusherService(services, pusher, Defaults.Interval);
12+
}
13+
914
public static IServiceCollection AddMetricPusherService(this IServiceCollection services, IMetricPusher pusher, TimeSpan interval)
1015
{
1116
if (pusher == null)

tests/MetricPusherServiceTests.cs

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,45 @@
11
using System.Threading;
22
using System.Threading.Tasks;
33

4-
namespace Prometheus.Client.MetricPusher.HostedService.Tests
4+
namespace Prometheus.Client.MetricPusher.HostedService.Tests;
5+
6+
public class MetricPusherServiceTests
57
{
6-
public class MetricPusherServiceTests
8+
[Fact]
9+
public async Task WithDefaultInterval_PushMetricPeriodically()
10+
{
11+
var metricPusherMock = Substitute.For<IMetricPusher>();
12+
var metricPusherService = new MetricPusherService(metricPusherMock);
13+
var canellationToken = Arg.Any<CancellationToken>();
14+
15+
await metricPusherService.StartAsync(canellationToken);
16+
await Task.Delay(GetDelay(1), canellationToken);
17+
await metricPusherService.StopAsync(canellationToken);
18+
19+
await metricPusherMock.Received(3).PushAsync();
20+
}
21+
22+
[Theory]
23+
[InlineData(1)]
24+
[InlineData(2)]
25+
[InlineData(3)]
26+
[InlineData(5)]
27+
public async Task WithGivenInterval_PushMetricPeriodically(int seconds)
28+
{
29+
var metricPusherMock = Substitute.For<IMetricPusher>();
30+
var metricPusherService = new MetricPusherService(metricPusherMock, TimeSpan.FromSeconds(seconds));
31+
var canellationToken = Arg.Any<CancellationToken>();
32+
33+
await metricPusherService.StartAsync(canellationToken);
34+
await Task.Delay(GetDelay(seconds), canellationToken);
35+
await metricPusherService.StopAsync(canellationToken);
36+
37+
await metricPusherMock.Received(3).PushAsync();
38+
}
39+
40+
private static TimeSpan GetDelay(int seconds)
741
{
8-
[Fact]
9-
public async Task WithGivenInterval_PushMetricPeriodically()
10-
{
11-
var metricPusherMock = Substitute.For<IMetricPusher>();
12-
var metricPusherService = new MetricPusherService(metricPusherMock, TimeSpan.FromSeconds(1));
13-
var canellationToken = Arg.Any<CancellationToken>();
14-
15-
await metricPusherService.StartAsync(canellationToken);
16-
await Task.Delay(TimeSpan.FromSeconds(1), canellationToken);
17-
await metricPusherService.StopAsync(canellationToken);
18-
19-
await metricPusherMock.Received(3).PushAsync();
20-
}
42+
var milliseconds = seconds * 1000 + 100;
43+
return TimeSpan.FromMilliseconds(milliseconds);
2144
}
2245
}
Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,54 @@
11
using Microsoft.Extensions.DependencyInjection;
22
using Microsoft.Extensions.Hosting;
33

4-
namespace Prometheus.Client.MetricPusher.HostedService.Tests
4+
namespace Prometheus.Client.MetricPusher.HostedService.Tests;
5+
6+
public class ServiceCollecttionExtensionsTests
57
{
6-
public class ServiceCollecttionExtensionsTests
8+
[Fact]
9+
public void AddMetricPusherService_WithNullMetricPusher_ThrowsArgumentNullException()
10+
{
11+
var servicesCollection = Substitute.For<IServiceCollection>();
12+
13+
Action act = () => servicesCollection.AddMetricPusherService(null, TimeSpan.FromSeconds(1));
14+
15+
act.Should().Throw<ArgumentNullException>();
16+
}
17+
18+
[Fact]
19+
public void AddMetricPusherService_WithZeroTimeInterval_ThrowsArgumentOutOfRangeException()
720
{
8-
[Fact]
9-
public void AddMetricPusherService_WithNullMetricPusher_ThrowsArgumentNullException()
10-
{
11-
var servicesCollection = Substitute.For<IServiceCollection>();
21+
var servicesCollection = Substitute.For<IServiceCollection>();
22+
var metricPusher = Substitute.For<IMetricPusher>();
1223

13-
Action act = () => servicesCollection.AddMetricPusherService(null, TimeSpan.FromSeconds(1));
24+
Action act = () => servicesCollection.AddMetricPusherService(metricPusher, TimeSpan.Zero);
1425

15-
act.Should().Throw<ArgumentNullException>();
16-
}
26+
act.Should().Throw<ArgumentOutOfRangeException>();
27+
}
1728

18-
[Fact]
19-
public void AddMetricPusherService_WithZeroTimeInterval_ThrowsArgumentOutOfRangeException()
20-
{
21-
var servicesCollection = Substitute.For<IServiceCollection>();
22-
var metricPusher = Substitute.For<IMetricPusher>();
29+
[Fact]
30+
public void AddMetricPusherService_WithDefaultInterval_AddsMetricPusherServiceInServiceCollection()
31+
{
32+
var servicesCollection = new ServiceCollection();
33+
var metricPusher = Substitute.For<IMetricPusher>();
2334

24-
Action act = () => servicesCollection.AddMetricPusherService(metricPusher, TimeSpan.Zero);
35+
servicesCollection.AddMetricPusherService(metricPusher);
36+
var provider = servicesCollection.BuildServiceProvider();
37+
var service = provider.GetRequiredService<IHostedService>();
2538

26-
act.Should().Throw<ArgumentOutOfRangeException>();
27-
}
39+
service.Should().BeOfType<MetricPusherService>();
40+
}
2841

29-
[Fact]
30-
public void AddMetricPusherService_WithValidParameterValues_AddsMetricPusherServiceInServiceCollection()
31-
{
32-
var servicesCollection = new ServiceCollection();
33-
var metricPusher = Substitute.For<IMetricPusher>();
42+
[Fact]
43+
public void AddMetricPusherService_WithValidParameterValues_AddsMetricPusherServiceInServiceCollection()
44+
{
45+
var servicesCollection = new ServiceCollection();
46+
var metricPusher = Substitute.For<IMetricPusher>();
3447

35-
servicesCollection.AddMetricPusherService(metricPusher, TimeSpan.FromSeconds(1));
36-
var provider = servicesCollection.BuildServiceProvider();
37-
var service = provider.GetRequiredService<IHostedService>();
48+
servicesCollection.AddMetricPusherService(metricPusher, TimeSpan.FromSeconds(1));
49+
var provider = servicesCollection.BuildServiceProvider();
50+
var service = provider.GetRequiredService<IHostedService>();
3851

39-
service.Should().BeOfType<MetricPusherService>();
40-
}
52+
service.Should().BeOfType<MetricPusherService>();
4153
}
4254
}

0 commit comments

Comments
 (0)