/dotent-multiprocess

Observe and test multiprocess services

Primary LanguageC#

https://docs.microsoft.com/en-us/dotnet/architecture/microservices/multi-container-microservice-net-applications/background-tasks-with-ihostedservice

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();
    }
}