using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using MoShiro.Protocol;
namespace MoShiro.Backend.Application;
///
/// 定时去镜像仓库取各组件(Agent、Backend 自己)最新的签名清单:CI 把清单登记给面板那一步是尽力而为的(网络不通只警告),
/// 面板自己也去仓库取,Backend 的更新通知和节点的更新建议就不依赖那一步。取回来的清单要用发布公钥验过签才登记。
///
public sealed partial class ReleasePoller : BackgroundService
{
private static readonly TimeSpan s_startupDelay = TimeSpan.FromSeconds(20);
private static readonly TimeSpan s_interval = TimeSpan.FromMinutes(5);
private static readonly string[] s_components = [ReleaseService.AgentComponent, ReleaseService.BackendComponent];
private readonly ReleaseService _releases;
private readonly TimeProvider _time;
private readonly ILogger _log;
public ReleasePoller(ReleaseService releases, TimeProvider time, ILogger log)
{
_releases = releases;
_time = time;
_log = log;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
try
{
await Task.Delay(s_startupDelay, _time, stoppingToken);
using var timer = new PeriodicTimer(s_interval, _time);
do
{
foreach (string component in s_components)
{
try
{
await _releases.GetOrFetchAsync(component, stoppingToken);
}
catch (Exception ex) when (ex is not OperationCanceledException)
{
LogFailed(ex, component);
}
}
}
while (await timer.WaitForNextTickAsync(stoppingToken));
}
catch (OperationCanceledException)
{
// 后端正在停止
}
}
[LoggerMessage(Level = LogLevel.Warning, Message = "could not check the registry for the latest {Component} release")]
private partial void LogFailed(Exception exception, string component);
}