diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/HostedServices/BackgroundService.cs b/src/Services/Ordering/Ordering.API/Infrastructure/HostedServices/BackgroundService.cs
new file mode 100644
index 000000000..205b3c75a
--- /dev/null
+++ b/src/Services/Ordering/Ordering.API/Infrastructure/HostedServices/BackgroundService.cs
@@ -0,0 +1,83 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+using Microsoft.Extensions.Hosting;
+
+namespace Ordering.API.Infrastructure.HostedServices
+{
+ // Copyright (c) .NET Foundation. All rights reserved.
+ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+ ///
+ /// Base class for implementing a long running .
+ /// IMPORTANT: This base class is implemented in .NET Core 2.1 - Since this microservice is still in .NET Core 2.0, we're using the class within the project
+ /// When .NET Core 2.1 is released, this class should be removed and you should use the use implemented by the framework
+ /// https://github.com/aspnet/Hosting/blob/712c992ca827576c05923e6a134ca0bec87af4df/src/Microsoft.Extensions.Hosting.Abstractions/BackgroundService.cs
+ ///
+ ///
+ public abstract class BackgroundService : IHostedService, IDisposable
+ {
+ private Task _executingTask;
+ private readonly CancellationTokenSource _stoppingCts = new CancellationTokenSource();
+
+ ///
+ /// This method is called when the starts. The implementation should return a task that represents
+ /// the lifetime of the long running operation(s) being performed.
+ ///
+ /// Triggered when is called.
+ /// A that represents the long running operations.
+ protected abstract Task ExecuteAsync(CancellationToken stoppingToken);
+
+ ///
+ /// Triggered when the application host is ready to start the service.
+ ///
+ /// Indicates that the start process has been aborted.
+ public virtual Task StartAsync(CancellationToken cancellationToken)
+ {
+ // Store the task we're executing
+ _executingTask = ExecuteAsync(_stoppingCts.Token);
+
+ // If the task is completed then return it, this will bubble cancellation and failure to the caller
+ if (_executingTask.IsCompleted)
+ {
+ return _executingTask;
+ }
+
+ // Otherwise it's running
+ return Task.CompletedTask;
+ }
+
+ ///
+ /// Triggered when the application host is performing a graceful shutdown.
+ ///
+ /// Indicates that the shutdown process should no longer be graceful.
+ public virtual async Task StopAsync(CancellationToken cancellationToken)
+ {
+ // Stop called without start
+ if (_executingTask == null)
+ {
+ return;
+ }
+
+ try
+ {
+ // Signal cancellation to the executing method
+ _stoppingCts.Cancel();
+ }
+ finally
+ {
+ // Wait until the task completes or the stop token triggers
+ await Task.WhenAny(_executingTask, Task.Delay(Timeout.Infinite, cancellationToken));
+ }
+
+ }
+
+ public virtual void Dispose()
+ {
+ _stoppingCts.Cancel();
+ }
+ }
+
+
+}
diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/HostedServices/GracePeriodManagerService.cs b/src/Services/Ordering/Ordering.API/Infrastructure/HostedServices/GracePeriodManagerService.cs
index 3fa70e20b..26017dfd0 100644
--- a/src/Services/Ordering/Ordering.API/Infrastructure/HostedServices/GracePeriodManagerService.cs
+++ b/src/Services/Ordering/Ordering.API/Infrastructure/HostedServices/GracePeriodManagerService.cs
@@ -12,8 +12,7 @@
using System.Threading;
using System.Threading.Tasks;
- public class GracePeriodManagerService
- : HostedService
+ public class GracePeriodManagerService : BackgroundService
{
private readonly OrderingSettings _settings;
private readonly ILogger _logger;
@@ -25,26 +24,28 @@
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_eventBus = eventBus ?? throw new ArgumentNullException(nameof(eventBus));
-
_settings = settings?.Value ?? throw new ArgumentNullException(nameof(settings));
}
- protected override async Task ExecuteAsync(CancellationToken cancellationToken)
+ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
- while (true)
+ _logger.LogDebug($"GracePeriod background task is starting.");
+
+ stoppingToken.Register(() => _logger.LogDebug($"#1 GracePeriod background task is stopping."));
+
+ while (!stoppingToken.IsCancellationRequested)
{
- if (cancellationToken.IsCancellationRequested)
- {
- break;
- }
+ _logger.LogDebug($"GracePeriod background task is doing background work.");
CheckConfirmedGracePeriodOrders();
- await Task.Delay(_settings.CheckUpdateTime, cancellationToken);
+ await Task.Delay(_settings.CheckUpdateTime, stoppingToken);
continue;
}
+ _logger.LogDebug($"GracePeriod background task is stopping.");
+
await Task.CompletedTask;
}
@@ -54,10 +55,11 @@
var orderIds = GetConfirmedGracePeriodOrders();
+ _logger.LogDebug($"GracePeriod sent a .");
foreach (var orderId in orderIds)
{
- var confirmGracePeriodEvent = new GracePeriodConfirmedIntegrationEvent(orderId);
- _eventBus.Publish(confirmGracePeriodEvent);
+ var gracePeriodConfirmedEvent = new GracePeriodConfirmedIntegrationEvent(orderId);
+ _eventBus.Publish(gracePeriodConfirmedEvent);
}
}
diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/HostedServices/HostedService.cs b/src/Services/Ordering/Ordering.API/Infrastructure/HostedServices/HostedService.cs
deleted file mode 100644
index 98ee4907a..000000000
--- a/src/Services/Ordering/Ordering.API/Infrastructure/HostedServices/HostedService.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-using Microsoft.Extensions.Hosting;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace Ordering.API.Infrastructure.HostedServices
-{
- public abstract class HostedService : IHostedService
- {
- // Example untested base class code kindly provided by David Fowler: https://gist.github.com/davidfowl/a7dd5064d9dcf35b6eae1a7953d615e3
-
- private Task _executingTask;
- private CancellationTokenSource _cts;
-
- public Task StartAsync(CancellationToken cancellationToken)
- {
- // Create a linked token so we can trigger cancellation outside of this token's cancellation
- _cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
-
- // Store the task we're executing
- _executingTask = ExecuteAsync(_cts.Token);
-
- // If the task is completed then return it, otherwise it's running
- return _executingTask.IsCompleted ? _executingTask : Task.CompletedTask;
- }
-
- public async Task StopAsync(CancellationToken cancellationToken)
- {
- // Stop called without start
- if (_executingTask == null)
- {
- return;
- }
-
- // Signal cancellation to the executing method
- _cts.Cancel();
-
- // Wait until the task completes or the stop token triggers
- await Task.WhenAny(_executingTask, Task.Delay(-1, cancellationToken));
-
- // Throw if cancellation triggered
- cancellationToken.ThrowIfCancellationRequested();
- }
-
- // Derived classes should override this and execute a long running method until
- // cancellation is requested
- protected abstract Task ExecuteAsync(CancellationToken cancellationToken);
- }
-}