chore: initial project import
This commit is contained in:
commit
26620707a0
347 files changed
+56172
No files matched your search
@@ -0,0 +1,75 @@
|
||||
using Fleet.Core;
|
||||
using Fleet.Link;
|
||||
using Monitor.Measurement;
|
||||
using Monitor.Protocol;
|
||||
|
||||
namespace Monitor.Agent;
|
||||
|
||||
/// <summary>
|
||||
/// Probe 的列块到达之后:找到对应的流 → 与 Agent 在数据面记录的列合并 → 盖章(块头、时钟锚点)→ 编码 → 放进发件箱(通道 16)。
|
||||
/// 找不到对应流的列块(任务已经被撤销、测试已经结束)被丢弃并计数;这只会发生在配置变更的瞬间。
|
||||
/// </summary>
|
||||
public sealed class ChunkAssembler
|
||||
{
|
||||
private readonly StreamRegistry _streams;
|
||||
private readonly MonoClock _clock;
|
||||
private readonly AgentCounters _counters;
|
||||
private readonly Outbox _outbox;
|
||||
private readonly NodeId _agent;
|
||||
private readonly TimeProvider _time;
|
||||
private readonly INodeLog _log;
|
||||
|
||||
public ChunkAssembler(StreamRegistry streams, MonoClock clock, AgentCounters counters, Outbox outbox, NodeId agent, TimeProvider time, INodeLog log)
|
||||
{
|
||||
_streams = streams;
|
||||
_clock = clock;
|
||||
_counters = counters;
|
||||
_outbox = outbox;
|
||||
_agent = agent;
|
||||
_time = time;
|
||||
_log = log;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理某个 Probe 交来的一个列块(已经解码)。返回是否被接受。
|
||||
/// 块头里的 <c>probe_id</c> 以认证过的会话为准(Probe 自报的值不可信),别的 Probe 的流也不会被命中。
|
||||
/// </summary>
|
||||
public bool Accept(RawChunk fragment, ProbeSession probe)
|
||||
{
|
||||
RawChunkHeader header = fragment.Header;
|
||||
StreamInfo? stream = header switch
|
||||
{
|
||||
{ TestId: { } test, Phase: { } phase } => _streams.FindByTest(test, phase) is { } found && ReferenceEquals(found.Owner, probe) ? found : null,
|
||||
{ TaskId: { } task } => _streams.FindByTask(task, probe),
|
||||
_ => null,
|
||||
};
|
||||
header.ProbeId = new ProbeId(probe.ProbeId);
|
||||
KindSpec? spec = stream is null ? null : Kinds.Find(stream.Kind);
|
||||
if (stream is null || spec is null || spec.Id != header.Kind)
|
||||
{
|
||||
_counters.FragmentDiscarded();
|
||||
return false;
|
||||
}
|
||||
|
||||
Result<IReadOnlyList<RawStream>> merged = FragmentMerger.Merge(spec, fragment, stream.Id, _streams);
|
||||
if (!merged.TryGet(out IReadOnlyList<RawStream>? streams, out FleetError? error))
|
||||
{
|
||||
_log.Warn("fragment discarded", ("kind", spec.Id), ("err", error.Code));
|
||||
_counters.FragmentDiscarded();
|
||||
stream.FragmentDone();
|
||||
return false;
|
||||
}
|
||||
|
||||
RawChunk chunk = ChunkFinalizer.Finalize(spec, fragment, streams, _agent, _clock.Anchor(), stream.Params.Values, stream.Port, ChunkId.New(_time));
|
||||
Emit(chunk);
|
||||
_counters.FragmentAccepted();
|
||||
stream.FragmentDone();
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>Agent 自己采集的块(目标任务)直接发出。</summary>
|
||||
public void Emit(RawChunk chunk)
|
||||
{
|
||||
_outbox.Enqueue(MonitorChannels.RawChunk, chunk.Header.ChunkId.Value, RawChunkCodec.Encode(chunk));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user