Namespaces, assemblies, projects and directories, the solution, binaries, images, systemd units, config paths, environment variables, protocol method names, the media type and the raw chunk magic all move to MoShiro/moshiro. Existing data and deployments are not compatible and must be recreated. Also fix the architecture tests after the solution layout change and make the update tests independent of their order.
48 lines
1.6 KiB
C#
48 lines
1.6 KiB
C#
namespace MoShiro.Measurement;
|
|
|
|
/// <summary>一个运行中的积木:自己的取消令牌和后台任务。Probe 和 Agent 共用。</summary>
|
|
public sealed class RunningBlock : IDisposable
|
|
{
|
|
private readonly CancellationTokenSource _cts = new();
|
|
|
|
private RunningBlock(IBlock block, string signature)
|
|
{
|
|
Block = block;
|
|
Signature = signature;
|
|
Completion = Task.CompletedTask;
|
|
}
|
|
|
|
public IBlock Block { get; }
|
|
|
|
/// <summary>参数、端口或流编号变化时调和器据此重启积木。</summary>
|
|
public string Signature { get; }
|
|
|
|
/// <summary>积木自己结束(单向数据流的发送端)或失败(<see cref="BlockFaultException"/>)时完成;被 <see cref="StopAsync"/> 停止时正常完成。</summary>
|
|
public Task Completion { get; private set; }
|
|
|
|
public static RunningBlock Start(IBlock block, string signature)
|
|
{
|
|
var running = new RunningBlock(block, signature);
|
|
running.Completion = Task.Run(() => block.RunAsync(running._cts.Token), CancellationToken.None);
|
|
return running;
|
|
}
|
|
|
|
/// <summary>停止积木并等它退出(最多 5 秒)。</summary>
|
|
public async Task StopAsync()
|
|
{
|
|
await _cts.CancelAsync();
|
|
try
|
|
{
|
|
await Completion.WaitAsync(TimeSpan.FromSeconds(5));
|
|
}
|
|
catch (Exception ex) when (ex is OperationCanceledException or TimeoutException or BlockFaultException)
|
|
{
|
|
// 没有及时退出或者已经失败:不再等
|
|
}
|
|
|
|
Dispose();
|
|
}
|
|
|
|
public void Dispose() => _cts.Dispose();
|
|
}
|