refactor!: rename the project from Monitor to MoShiro [CI]
ci/woodpecker/push/main-amd64-build Pipeline was successful
ci/woodpecker/push/main-amd64-build Pipeline was successful
Namespaces, assemblies, solution, binaries, images, systemd units, config paths, environment variables, protocol methods and the Linux user are all renamed. Breaking: existing databases, node identities and installed units must be recreated.
This commit is contained in:
1 parent
27ac7fb787
commit
2e146d4da7
309 files changed
+1565
-1572
No files matched your search
@@ -0,0 +1,87 @@
|
||||
using System.Text.Json;
|
||||
using Fleet.Core;
|
||||
using Fleet.Link;
|
||||
using MoShiro.Measurement;
|
||||
using MoShiro.Protocol;
|
||||
|
||||
namespace MoShiro.Probe;
|
||||
|
||||
/// <summary>
|
||||
/// 估计 Agent 单调时钟 − Probe 单调时钟:每次 <c>moshiro.clock</c> 往返取中点,在最近 8 次里取往返最短的一次
|
||||
/// (往返越短,对称性假设的误差越小)。Probe 的列块头里带着这个偏移,Backend 据此对齐两端的时间戳。
|
||||
/// </summary>
|
||||
public sealed class ClockEstimator
|
||||
{
|
||||
private const int Window = 8;
|
||||
|
||||
private readonly object _gate = new();
|
||||
private readonly Queue<(long RoundTripUs, long OffsetUs)> _samples = new();
|
||||
|
||||
public long OffsetUs { get; private set; }
|
||||
|
||||
public bool HasEstimate { get; private set; }
|
||||
|
||||
public void Add(long sendUs, long agentUs, long receiveUs)
|
||||
{
|
||||
lock (_gate)
|
||||
{
|
||||
_samples.Enqueue((receiveUs - sendUs, agentUs - ((sendUs + receiveUs) / 2)));
|
||||
while (_samples.Count > Window)
|
||||
{
|
||||
_samples.Dequeue();
|
||||
}
|
||||
|
||||
OffsetUs = _samples.MinBy(s => s.RoundTripUs).OffsetUs;
|
||||
HasEstimate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 把 Probe 一侧的行交给这个 Agent:补全块头 → 编码 → 放进会话的发件箱(通道 17,至少一次,有界)。
|
||||
/// 发件箱的内容在连接断开重连之后重发;发件箱满了丢弃最旧的。
|
||||
/// </summary>
|
||||
public sealed class FragmentShipper : IFragmentSink
|
||||
{
|
||||
private readonly Outbox _outbox;
|
||||
private readonly NodeId _agent;
|
||||
private readonly ProbeId _probe;
|
||||
private readonly ClockEstimator _clock;
|
||||
private readonly TimeProvider _time;
|
||||
|
||||
public FragmentShipper(Outbox outbox, NodeId agent, ProbeId probe, ClockEstimator clock, TimeProvider time)
|
||||
{
|
||||
_outbox = outbox;
|
||||
_agent = agent;
|
||||
_probe = probe;
|
||||
_clock = clock;
|
||||
_time = time;
|
||||
}
|
||||
|
||||
public void Ship(string kind, FragmentScope scope, IReadOnlyList<RawStream> streams, IReadOnlyDictionary<string, JsonElement>? parameters, long startUtcMs, int durationMs, int port)
|
||||
{
|
||||
var header = new RawChunkHeader
|
||||
{
|
||||
ChunkId = ChunkId.New(_time),
|
||||
Kind = kind,
|
||||
TaskId = scope.Task,
|
||||
TestId = scope.Test,
|
||||
Phase = scope.Phase,
|
||||
AgentId = _agent,
|
||||
ProbeId = _probe,
|
||||
Port = port,
|
||||
StartUtcMs = startUtcMs,
|
||||
DurationMs = Math.Max(1, durationMs),
|
||||
Clock = new ChunkClock { ProbeOffsetUs = _clock.OffsetUs },
|
||||
};
|
||||
if (parameters is not null)
|
||||
{
|
||||
foreach ((string key, JsonElement value) in parameters)
|
||||
{
|
||||
header.Params[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
_outbox.Enqueue(MoShiroChannels.ColumnBlock, header.ChunkId.Value, RawChunkCodec.Encode(new RawChunk(header, streams)));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user