using BirthdayBot.BackgroundServices;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace BirthdayBot
{
///
/// Handles the execution of periodic background tasks.
///
class BackgroundServiceRunner
{
const int Interval = 8 * 60; // Tick interval in seconds. Adjust as needed.
private List _workers;
private readonly CancellationTokenSource _workerCancel;
private Task _workerTask;
internal BirthdayRoleUpdate BirthdayUpdater { get; }
public BackgroundServiceRunner(BirthdayBot instance)
{
_workerCancel = new CancellationTokenSource();
BirthdayUpdater = new BirthdayRoleUpdate(instance);
_workers = new List()
{
{new GuildStatistics(instance)},
{new Heartbeat(instance)},
{BirthdayUpdater}
};
}
public void Start()
{
_workerTask = Task.Factory.StartNew(WorkerLoop, _workerCancel.Token,
TaskCreationOptions.LongRunning, TaskScheduler.Default);
}
public async Task Cancel()
{
_workerCancel.Cancel();
await _workerTask;
}
///
/// *The* background task. Executes service tasks and handles errors.
///
private async Task WorkerLoop()
{
while (!_workerCancel.IsCancellationRequested)
{
try
{
// Delay a bit before we start (or continue) work.
await Task.Delay(Interval * 1000, _workerCancel.Token);
// Execute background tasks.
var tasks = new List();
foreach (var service in _workers)
{
tasks.Add(service.OnTick());
}
await Task.WhenAll(tasks);
}
catch (TaskCanceledException)
{
return;
}
catch (Exception ex)
{
Program.Log("Background task", "Unhandled exception during background task execution:");
Program.Log("Background task", ex.ToString());
}
}
}
}
}