2022-12-02 14:45:20 +05:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
2023-10-08 21:20:28 +05:00
|
|
|
|
namespace AsbCloudInfrastructure.Background;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// Очередь работ
|
|
|
|
|
/// </para>
|
|
|
|
|
/// Не периодические задачи будут возвращаться первыми, как самые приоритетные.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class WorkStore
|
2022-12-02 14:45:20 +05:00
|
|
|
|
{
|
2023-10-08 21:20:28 +05:00
|
|
|
|
private readonly List<WorkPeriodic> periodics = new(8);
|
|
|
|
|
|
2022-12-02 14:45:20 +05:00
|
|
|
|
/// <summary>
|
2023-10-08 21:20:28 +05:00
|
|
|
|
/// Список периодических задач
|
|
|
|
|
/// </summary>
|
|
|
|
|
public IEnumerable<WorkPeriodic> Periodics => periodics;
|
2023-10-09 13:12:45 +05:00
|
|
|
|
|
2023-10-08 21:20:28 +05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Работы выполняемые один раз
|
2022-12-02 14:45:20 +05:00
|
|
|
|
/// </summary>
|
2023-10-08 21:20:28 +05:00
|
|
|
|
public Queue<Work> RunOnceQueue { get; private set; } = new(8);
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2023-10-09 13:12:45 +05:00
|
|
|
|
/// Завершившиеся с ошибкой
|
|
|
|
|
/// </summary>
|
|
|
|
|
public CyclycArray<Work> Felled { get; } = new(16);
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Добавить фоновую работу выполняющуюся с заданным периодом
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="T"></typeparam>
|
|
|
|
|
/// <param name="period"></param>
|
|
|
|
|
public void AddPeriodic<T>(TimeSpan period)
|
|
|
|
|
where T : Work, new()
|
|
|
|
|
{
|
|
|
|
|
var work = new T();
|
|
|
|
|
var periodic = new WorkPeriodic(work, period);
|
|
|
|
|
periodics.Add(periodic);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Добавить фоновую работу выполняющуюся с заданным периодом
|
2023-10-08 21:20:28 +05:00
|
|
|
|
/// </summary>
|
2023-10-09 13:12:45 +05:00
|
|
|
|
/// <param name="work"></param>
|
|
|
|
|
/// <param name="period"></param>
|
2023-10-08 21:20:28 +05:00
|
|
|
|
public void AddPeriodic(Work work, TimeSpan period)
|
2022-12-02 14:45:20 +05:00
|
|
|
|
{
|
2023-10-08 21:20:28 +05:00
|
|
|
|
var periodic = new WorkPeriodic(work, period);
|
|
|
|
|
periodics.Add(periodic);
|
|
|
|
|
}
|
2022-12-02 14:45:20 +05:00
|
|
|
|
|
2023-10-08 21:20:28 +05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Удаление работы по ID из одноразовой очереди
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="id"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public bool TryRemoveFromRunOnceQueue(string id)
|
|
|
|
|
{
|
|
|
|
|
var work = RunOnceQueue.FirstOrDefault(w => w.Id == id);
|
|
|
|
|
if (work is not null)
|
2022-12-02 14:45:20 +05:00
|
|
|
|
{
|
2023-10-08 21:20:28 +05:00
|
|
|
|
RunOnceQueue = new Queue<Work>(RunOnceQueue.Where(w => w.Id != id));
|
|
|
|
|
return true;
|
2022-12-02 14:45:20 +05:00
|
|
|
|
}
|
|
|
|
|
|
2023-10-08 21:20:28 +05:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2022-12-02 14:45:20 +05:00
|
|
|
|
|
2023-10-08 21:20:28 +05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// Возвращает приоритетную задачу.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// <para>
|
|
|
|
|
/// Если приоритетные закончились, то ищет ближайшую периодическую.
|
|
|
|
|
/// Если до старта ближайшей периодической работы меньше 20 сек,
|
|
|
|
|
/// то этой задаче устанавливается время последнего запуска в now и она возвращается.
|
|
|
|
|
/// Если больше 20 сек, то возвращается null.
|
|
|
|
|
/// </para>
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="maxTimeToNextWork"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public Work? GetNext()
|
|
|
|
|
{
|
|
|
|
|
if (RunOnceQueue.Any())
|
|
|
|
|
return RunOnceQueue.Dequeue();
|
2022-12-02 14:45:20 +05:00
|
|
|
|
|
2023-10-08 21:20:28 +05:00
|
|
|
|
var work = GetNextPeriodic();
|
|
|
|
|
if (work is null || work.NextStart > DateTime.Now)
|
|
|
|
|
return null;
|
2022-12-02 14:45:20 +05:00
|
|
|
|
|
2023-10-08 21:20:28 +05:00
|
|
|
|
return work.Work;
|
2022-12-02 14:45:20 +05:00
|
|
|
|
}
|
2023-04-18 16:22:53 +05:00
|
|
|
|
|
2023-10-08 21:20:28 +05:00
|
|
|
|
private WorkPeriodic? GetNextPeriodic()
|
|
|
|
|
{
|
|
|
|
|
var work = Periodics
|
|
|
|
|
.OrderBy(w => w.NextStart)
|
|
|
|
|
.FirstOrDefault();
|
|
|
|
|
return work;
|
|
|
|
|
}
|
2022-12-02 14:45:20 +05:00
|
|
|
|
}
|