Confguration params :
publisherThreadsToRun = 1;
paasSubscriptoinThreadsToRun = 2;
publishFrequencyInMs= 25;
Design a service like:
public class Publisher : BackgroundService
{
private readonly ILogger<Publisher> _logger;
private readonly OrderingBackgroundSettings _settings;
private readonly IEventBus _eventBus;
public Publisher(IOptions<OrderingBackgroundSettings> settings,
IEventBus eventBus,
ILogger<Publisher> logger)
{
// Constructor's parameters validations...
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogDebug($"Publisher is starting.");
stoppingToken.Register(() =>
_logger.LogDebug($" Publisher background task is stopping."));
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogDebug($"Publisher task doing background work.");
// Publish subscriptoin based on two factors
// - lastPublishTime - currentTime >= refreshRate
// AND
// - lastUpdateTime >= lastPublishTime
PublishAllSubscriptionThatNeedUpdates();
await Task.Delay(_settings.publishFrequencyInMs, stoppingToken);
}
_logger.LogDebug($"Publisher background task is stopping.");
}
.../...
}
Define a background service :
// Copyright (c) .NET Foundation. Licensed under the Apache License, Version 2.0.
/// <summary>
/// Base class for implementing a long running <see cref="IHostedService"/>.
/// </summary>
public abstract class BackgroundService : IHostedService, IDisposable
{
private Task _executingTask;
private readonly CancellationTokenSource _stoppingCts =
new CancellationTokenSource();
protected abstract Task ExecuteAsync(CancellationToken stoppingToken);
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;
}
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();
}
}