agent: unify listening and dialing with directed mutual measurements
Replace Probe with Agent across node runtime, Fleet contracts, backend state, API and storage. Report incoming sessions and outgoing link health through each Agent uplink, and retain directed link controls and retry. Update protocol fixtures and end-to-end coverage for the unified model; accept requested cancellation during the Fleet timeout test cleanup.
This commit is contained in:
1 parent
d5ebf29e57
commit
ad5efc62ff
206 files changed
+4202
-4964
No files matched your search
@@ -7,14 +7,14 @@ namespace MoShiro.TestSupport;
|
||||
/// <summary>每一个回显包的设定:上行或下行丢失,以及两个方向的单向时延(微秒)。</summary>
|
||||
public readonly record struct EchoPacket(bool LostUp, bool LostDown, long OwdUpUs, long OwdDownUs, long ProcessUs = 50);
|
||||
|
||||
/// <summary>合成原始块:用于测试、模拟器和离线工具。块头里的时钟锚点保证 Probe 与 Agent 时钟相差 <see cref="ProbeOffsetUs"/>。</summary>
|
||||
/// <summary>合成原始块:用于测试、模拟器和离线工具。块头里的时钟锚点保证 拨号方与监听方时钟相差 <see cref="DialerOffsetUs"/>。</summary>
|
||||
public static class ChunkFactory
|
||||
{
|
||||
/// <summary>合成块默认属于哪个 Probe(测试夹具在后端创建一个真实的 Probe 之后把它的 id 写在这里)。</summary>
|
||||
public static string DefaultProbe { get; set; } = "prb_test";
|
||||
/// <summary>合成块默认属于哪个拨号侧 Agent(测试夹具在后端创建一个真实的拨号侧 Agent 之后把它的 id 写在这里)。</summary>
|
||||
public static string DefaultDialer { get; set; } = "agt_dialer_test";
|
||||
|
||||
public const long AgentMonoAnchorUs = 1_000_000_000;
|
||||
public const long ProbeOffsetUs = 5_000_000;
|
||||
public const long DialerOffsetUs = 5_000_000;
|
||||
|
||||
public static RawChunkHeader Header(NodeId agent, string kind, long startUtcMs, int durationMs = 10_000, IReadOnlyDictionary<string, JsonElement>? parameters = null)
|
||||
{
|
||||
@@ -25,17 +25,17 @@ public static class ChunkFactory
|
||||
ChunkId = new ChunkId(Guid.CreateVersion7()),
|
||||
Kind = kind,
|
||||
AgentId = agent,
|
||||
ProbeId = new ProbeId(DefaultProbe),
|
||||
DialerId = new NodeId(DefaultDialer),
|
||||
Params = new Dictionary<string, JsonElement>(resolved.Values!.Values),
|
||||
Port = 7443,
|
||||
StartUtcMs = startUtcMs,
|
||||
DurationMs = durationMs,
|
||||
Clock = new ChunkClock { AgentMonoUs = AgentMonoAnchorUs, UtcMs = startUtcMs, ProbeOffsetUs = ProbeOffsetUs },
|
||||
Clock = new ChunkClock { ListenerMonoUs = AgentMonoAnchorUs, UtcMs = startUtcMs, DialerOffsetUs = DialerOffsetUs },
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>Probe 时钟下,距离块起点 <paramref name="offsetMs"/> 毫秒的时刻(微秒)。</summary>
|
||||
public static long ProbeUs(long offsetMs) => (offsetMs * 1000) + AgentMonoAnchorUs - ProbeOffsetUs;
|
||||
/// <summary>拨号方时钟下,距离块起点 <paramref name="offsetMs"/> 毫秒的时刻(微秒)。</summary>
|
||||
public static long DialerUs(long offsetMs) => (offsetMs * 1000) + AgentMonoAnchorUs - DialerOffsetUs;
|
||||
|
||||
public static long AgentUs(long offsetMs) => (offsetMs * 1000) + AgentMonoAnchorUs;
|
||||
|
||||
@@ -54,10 +54,10 @@ public static class ChunkFactory
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
EchoPacket p = packet(i);
|
||||
long t1 = ProbeUs((long)i * intervalMs);
|
||||
long t2 = t1 + ProbeOffsetUs + p.OwdUpUs;
|
||||
long t1 = DialerUs((long)i * intervalMs);
|
||||
long t2 = t1 + DialerOffsetUs + p.OwdUpUs;
|
||||
long t3 = t2 + p.ProcessUs;
|
||||
long t4 = t3 - ProbeOffsetUs + p.OwdDownUs;
|
||||
long t4 = t3 - DialerOffsetUs + p.OwdDownUs;
|
||||
msg.Add(i, 64, t1, p.LostUp ? null : t2, p.LostUp ? null : t3, p.LostUp || p.LostDown ? null : t4);
|
||||
}
|
||||
|
||||
@@ -91,14 +91,14 @@ public static class ChunkFactory
|
||||
int i = 0;
|
||||
foreach ((long tcp, long? tls, ConnectOutcomeCode outcome) in attempts)
|
||||
{
|
||||
builder.Add(i, ProbeUs(i * 5000L), outcome == ConnectOutcomeCode.Timeout ? null : tcp, tls, (long)outcome);
|
||||
builder.Add(i, DialerUs(i * 5000L), outcome == ConnectOutcomeCode.Timeout ? null : tcp, tls, (long)outcome);
|
||||
i++;
|
||||
}
|
||||
|
||||
return new RawChunk(Header(agent, "connect", startUtcMs), [builder.Build()]);
|
||||
}
|
||||
|
||||
/// <summary>udp_train:Agent 以固定间隔发包,Probe 记录收到的时刻;<paramref name="lossEvery"/> 为 N 时每 N 个包丢一个。</summary>
|
||||
/// <summary>udp_train:Agent 以固定间隔发包,Dialer 记录收到的时刻;<paramref name="lossEvery"/> 为 N 时每 N 个包丢一个。</summary>
|
||||
public static RawChunk Train(NodeId agent, long startUtcMs, double mbps, int phase, int seconds = 10, int lossEvery = 0, long owdUs = 20_000)
|
||||
{
|
||||
const int size = 1250;
|
||||
@@ -109,8 +109,8 @@ public static class ChunkFactory
|
||||
{
|
||||
long sendAgent = AgentMonoAnchorUs + (long)(i * intervalUs);
|
||||
bool lost = lossEvery > 0 && i % lossEvery == 0;
|
||||
long recvProbe = sendAgent + owdUs - ProbeOffsetUs;
|
||||
pkt.Add(i, size, sendAgent, lost ? null : recvProbe);
|
||||
long recvDialer = sendAgent + owdUs - DialerOffsetUs;
|
||||
pkt.Add(i, size, sendAgent, lost ? null : recvDialer);
|
||||
}
|
||||
|
||||
var parameters = new Dictionary<string, JsonElement>
|
||||
|
||||
Reference in new issue
Block a user