103 lines
2.7 KiB
C#
103 lines
2.7 KiB
C#
namespace Fleet.Hosting;
|
|
|
|
/// <summary>
|
|
/// 当前生效的定时重启:节点本地的设置优先;本地没有写时用面板下发的,面板改了之后立即重新排下一次,不需要重启进程。
|
|
/// </summary>
|
|
public sealed class RestartController : IDisposable
|
|
{
|
|
private readonly RestartSchedule? _local;
|
|
private readonly object _gate = new();
|
|
private RestartSchedule? _remote;
|
|
private readonly CancellationTokenSource _now = new();
|
|
private CancellationTokenSource _changed = new();
|
|
private string? _nowReason;
|
|
|
|
public RestartController(RestartSchedule? local = null)
|
|
{
|
|
_local = local;
|
|
}
|
|
|
|
/// <summary>本地有设置时为 true:面板下发的不生效。</summary>
|
|
public bool IsLocal => _local is not null;
|
|
|
|
public RestartSchedule? Current
|
|
{
|
|
get
|
|
{
|
|
lock (_gate)
|
|
{
|
|
return _local ?? _remote;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>当前设置被改动时会被取消的令牌;先取令牌、再取 <see cref="Current"/>,就不会漏掉中间的改动。</summary>
|
|
public CancellationToken ChangeToken
|
|
{
|
|
get
|
|
{
|
|
lock (_gate)
|
|
{
|
|
return _changed.Token;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>应用要求现在就有序退出(比如管理员请求更新);退出的原因,没有就是 null。</summary>
|
|
public string? NowReason
|
|
{
|
|
get
|
|
{
|
|
lock (_gate)
|
|
{
|
|
return _nowReason;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>应用要求现在就退出的令牌。</summary>
|
|
public CancellationToken NowToken => _now.Token;
|
|
|
|
/// <summary>要求进程现在就有序退出,由服务管理器拉起;不管有没有设置定时重启。</summary>
|
|
public void RequestNow(string reason)
|
|
{
|
|
lock (_gate)
|
|
{
|
|
_nowReason ??= reason;
|
|
}
|
|
|
|
_now.Cancel();
|
|
}
|
|
|
|
/// <summary>面板下发的设置;为空表示面板关闭了定时重启。返回 false 表示文本不合法(节点忽略它)。</summary>
|
|
public bool SetRemote(string? text)
|
|
{
|
|
RestartSchedule? schedule = null;
|
|
if (!string.IsNullOrWhiteSpace(text) && !RestartSchedule.TryParse(text, out schedule))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
CancellationTokenSource previous;
|
|
lock (_gate)
|
|
{
|
|
_remote = schedule;
|
|
previous = _changed;
|
|
_changed = new CancellationTokenSource();
|
|
}
|
|
|
|
previous.Cancel();
|
|
previous.Dispose();
|
|
return true;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
lock (_gate)
|
|
{
|
|
_changed.Dispose();
|
|
_now.Dispose();
|
|
}
|
|
}
|
|
}
|