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
+2
-2
@@ -1,7 +1,7 @@
|
||||
using System.Net;
|
||||
using Monitor.Protocol;
|
||||
using MoShiro.Protocol;
|
||||
|
||||
namespace Monitor.Measurement;
|
||||
namespace MoShiro.Measurement;
|
||||
|
||||
/// <summary>积木的公共部分:环境、参数、把行切成列块交出去。</summary>
|
||||
public abstract class BlockBase : IBlock
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
using Monitor.Protocol;
|
||||
using MoShiro.Protocol;
|
||||
|
||||
namespace Monitor.Measurement;
|
||||
namespace MoShiro.Measurement;
|
||||
|
||||
/// <summary>
|
||||
/// 一种采集方法(Kind)的两个角色:拨号方(Probe)和监听方(Agent),以及它能不能作为目标任务(Agent 自己探测一个地址,没有对端)运行。
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
using System.Net.Sockets;
|
||||
using Monitor.Protocol;
|
||||
using MoShiro.Protocol;
|
||||
|
||||
namespace Monitor.Measurement;
|
||||
namespace MoShiro.Measurement;
|
||||
|
||||
/// <summary>批量传输的收发循环(两端共用)。</summary>
|
||||
internal static class BulkIo
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using Monitor.Protocol;
|
||||
using MoShiro.Protocol;
|
||||
|
||||
namespace Monitor.Measurement;
|
||||
namespace MoShiro.Measurement;
|
||||
|
||||
/// <summary>
|
||||
/// 回显积木的行表(拨号方,行的主导方):发出时记 size、t1,回复到达时按序号回填 t4,到点把已经稳定的行切成列块。
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
using System.Security.Authentication;
|
||||
using Monitor.Protocol;
|
||||
using MoShiro.Protocol;
|
||||
|
||||
namespace Monitor.Measurement;
|
||||
namespace MoShiro.Measurement;
|
||||
|
||||
/// <summary>什么也不做的监听方:connect 的另一端就是 TCP 监听器本身(接受连接、认证失败就关闭),不需要积木,但需要占一个流编号。</summary>
|
||||
public sealed class IdleListener : BlockBase
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using Monitor.Protocol;
|
||||
using MoShiro.Protocol;
|
||||
|
||||
namespace Monitor.Measurement;
|
||||
namespace MoShiro.Measurement;
|
||||
|
||||
/// <summary>
|
||||
/// 单向数据流(UDP train),监听方(Agent,行的主导方):按声明的码率均匀发包,发出的每个包 (seq, size, t_send) 记在按序号的记录里,
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
using System.Net;
|
||||
using System.Text.Json;
|
||||
using Fleet.Core;
|
||||
using Monitor.Protocol;
|
||||
using MoShiro.Protocol;
|
||||
|
||||
namespace Monitor.Measurement;
|
||||
namespace MoShiro.Measurement;
|
||||
|
||||
/// <summary>
|
||||
/// 数据面会话:<c>session_id</c> 和密钥(由点对点握手里的 ECDH 派生)。两端的数据面包都用它认证。
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
namespace Monitor.Measurement;
|
||||
namespace MoShiro.Measurement;
|
||||
|
||||
/// <summary>节点的单调时钟(微秒):t1…t4、t_send、t_recv 都用它;Probe 和 Agent 各自一个,块头里的时钟锚点把它对应到 UTC。</summary>
|
||||
public sealed class MonoClock
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
using Monitor.Protocol;
|
||||
using MoShiro.Protocol;
|
||||
|
||||
namespace Monitor.Measurement;
|
||||
namespace MoShiro.Measurement;
|
||||
|
||||
/// <summary>
|
||||
/// 一侧记录的行:只含这一侧拥有的列(见 <see cref="StreamSpec.ColumnsOf"/>),按连接键(通常是 <c>seq</c>)索引的环形缓冲,
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
namespace Monitor.Measurement;
|
||||
namespace MoShiro.Measurement;
|
||||
|
||||
/// <summary>一个运行中的积木:自己的取消令牌和后台任务。Probe 和 Agent 共用。</summary>
|
||||
public sealed class RunningBlock : IDisposable
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
using System.Net;
|
||||
using System.Text.Json;
|
||||
using Monitor.Protocol;
|
||||
using MoShiro.Protocol;
|
||||
|
||||
namespace Monitor.Measurement;
|
||||
namespace MoShiro.Measurement;
|
||||
|
||||
/// <summary>节点的本地硬上限(写在本机配置里,Backend 无法修改)。</summary>
|
||||
public sealed class NodeLimits
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
using System.Text.Json;
|
||||
using Fleet.Core;
|
||||
using Monitor.Protocol;
|
||||
using MoShiro.Protocol;
|
||||
|
||||
namespace Monitor.Measurement;
|
||||
namespace MoShiro.Measurement;
|
||||
|
||||
/// <summary>Agent 单调时钟(微秒)与 UTC(毫秒)的对应关系:块头里的时钟锚点。</summary>
|
||||
public readonly record struct ClockAnchor(long AgentMonoUs, long UtcMs);
|
||||
+5
-5
@@ -1,8 +1,8 @@
|
||||
using System.Text.Json;
|
||||
using Fleet.Core;
|
||||
using Monitor.Protocol;
|
||||
using MoShiro.Protocol;
|
||||
|
||||
namespace Monitor.Measurement;
|
||||
namespace MoShiro.Measurement;
|
||||
|
||||
/// <summary>Agent 一侧为合并保留的按键记录(由正在运行的积木提供)。</summary>
|
||||
public interface IRecordSource
|
||||
@@ -29,7 +29,7 @@ public static class FragmentMerger
|
||||
StreamSpec? streamSpec = spec.FindStream(stream.Name);
|
||||
if (streamSpec is null)
|
||||
{
|
||||
return Result<IReadOnlyList<RawStream>>.Fail(MonitorErrors.ValidationFailed, $"stream {stream.Name} is not declared by {spec.Id}");
|
||||
return Result<IReadOnlyList<RawStream>>.Fail(MoShiroErrors.ValidationFailed, $"stream {stream.Name} is not declared by {spec.Id}");
|
||||
}
|
||||
|
||||
Result<RawStream> merged = Join(streamSpec, stream, fragment.Header, records.Records(streamId, stream.Name));
|
||||
@@ -71,7 +71,7 @@ public static class FragmentMerger
|
||||
RawColumn? key = probe.Find(spec.Key);
|
||||
if (key is null || probeColumns.Any(c => probe.Find(c.Name) is null))
|
||||
{
|
||||
return Result<RawStream>.Fail(MonitorErrors.ValidationFailed, $"a fragment of stream {spec.Name} needs the columns {string.Join(", ", new[] { spec.Key }.Concat(probeColumns.Select(c => c.Name)))}");
|
||||
return Result<RawStream>.Fail(MoShiroErrors.ValidationFailed, $"a fragment of stream {spec.Name} needs the columns {string.Join(", ", new[] { spec.Key }.Concat(probeColumns.Select(c => c.Name)))}");
|
||||
}
|
||||
|
||||
return spec.Driver == Side.Probe ? JoinOnProbeRows(spec, probe, key, agent) : JoinOnAgentRows(spec, probe, key, header, agent);
|
||||
@@ -118,7 +118,7 @@ public static class FragmentMerger
|
||||
{
|
||||
if (!TryGetRange(header, out uint from, out uint to))
|
||||
{
|
||||
return Result<RawStream>.Fail(MonitorErrors.ValidationFailed, $"a fragment of stream {spec.Name} must declare its sequence range");
|
||||
return Result<RawStream>.Fail(MoShiroErrors.ValidationFailed, $"a fragment of stream {spec.Name} must declare its sequence range");
|
||||
}
|
||||
|
||||
// 行取自 Agent 的记录:范围内发出过的每一个包都有一行,Probe 没有报告到达的就是丢失
|
||||
+2
-2
@@ -3,8 +3,8 @@
|
||||
<IsAotCompatible>true</IsAotCompatible>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<InternalsVisibleTo Include="Monitor.Measurement.Tests" />
|
||||
<InternalsVisibleTo Include="MoShiro.Measurement.Tests" />
|
||||
<AdditionalFiles Include="$(MSBuildThisFileDirectory)../../BannedSymbols.Node.txt" />
|
||||
<ProjectReference Include="..\Monitor.Protocol\Monitor.Protocol.csproj" />
|
||||
<ProjectReference Include="..\MoShiro.Protocol\MoShiro.Protocol.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
+2
-2
@@ -5,9 +5,9 @@ using System.Net.Sockets;
|
||||
using System.Security.Authentication;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using Monitor.Protocol;
|
||||
using MoShiro.Protocol;
|
||||
|
||||
namespace Monitor.Measurement;
|
||||
namespace MoShiro.Measurement;
|
||||
|
||||
/// <summary>拨号方的一条数据面 TCP 连接(已经完成 TLS 和首帧认证)。</summary>
|
||||
public sealed class TcpLink : IDisposable
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
using System.Buffers.Binary;
|
||||
using System.Net.Sockets;
|
||||
using Monitor.Protocol;
|
||||
using MoShiro.Protocol;
|
||||
|
||||
namespace Monitor.Measurement;
|
||||
namespace MoShiro.Measurement;
|
||||
|
||||
/// <summary>内核对一条 TCP 连接的采样(Linux <c>TCP_INFO</c>)。</summary>
|
||||
public readonly record struct TcpInfoSample(long SrttUs, long RttVarUs, long Cwnd, long TotalRetrans, long SegsOut, long BytesAcked);
|
||||
+2
-2
@@ -2,9 +2,9 @@ using System.Collections.Concurrent;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using Fleet.Core;
|
||||
using Monitor.Protocol;
|
||||
using MoShiro.Protocol;
|
||||
|
||||
namespace Monitor.Measurement;
|
||||
namespace MoShiro.Measurement;
|
||||
|
||||
/// <summary>一个通过校验的 UDP 包,交给按 <c>stream_id</c> 登记的处理函数。处理函数在接收循环里同步执行,不能阻塞。</summary>
|
||||
public readonly ref struct UdpDelivery
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using Monitor.Protocol;
|
||||
using MoShiro.Protocol;
|
||||
|
||||
namespace Monitor.Measurement;
|
||||
namespace MoShiro.Measurement;
|
||||
|
||||
/// <summary>
|
||||
/// 读出本机的系统名和架构,只用于在面板上展示。故意只取粗粒度的信息:
|
||||
+4
-4
@@ -1,12 +1,12 @@
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using Fleet.Core;
|
||||
using Monitor.Protocol;
|
||||
using MoShiro.Protocol;
|
||||
|
||||
namespace Monitor.Measurement;
|
||||
namespace MoShiro.Measurement;
|
||||
|
||||
/// <summary>
|
||||
/// 节点进程和宿主机更新器之间的文件交换(容器里 <c>/etc/monitor</c>,也就是数据目录):
|
||||
/// 节点进程和宿主机更新器之间的文件交换(容器里 <c>/etc/moshiro</c>,也就是数据目录):
|
||||
/// 节点把面板发来的清单和签名写进 <c>update/</c>,把「更新」请求写成 <c>update/apply.request</c>;更新器验签并更新,状态由宿主更新器写在只读挂载的 <c>update-status/status.json</c>。
|
||||
/// 节点进程不执行任何命令,也不信任清单的内容(验签在宿主机上)。没有安装更新器时目录写不了或没人读,调用只是返回 false。
|
||||
/// </summary>
|
||||
@@ -88,7 +88,7 @@ public sealed class UpdateBridge
|
||||
return null;
|
||||
}
|
||||
|
||||
return JsonSerializer.Deserialize(File.ReadAllBytes(_statusFile), MonitorJsonContext.Default.UpdateStatus);
|
||||
return JsonSerializer.Deserialize(File.ReadAllBytes(_statusFile), MoShiroJsonContext.Default.UpdateStatus);
|
||||
}
|
||||
catch (Exception ex) when (ex is IOException or UnauthorizedAccessException or JsonException)
|
||||
{
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
namespace Monitor.Protocol;
|
||||
namespace MoShiro.Protocol;
|
||||
|
||||
[Flags]
|
||||
public enum Scope
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
namespace Monitor.Protocol;
|
||||
namespace MoShiro.Protocol;
|
||||
|
||||
/// <summary>
|
||||
/// Kind 目录。新增一种采集方法 = 在这里加一个静态字段并放进 <see cref="All"/>;
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
using System.Globalization;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Monitor.Protocol;
|
||||
namespace MoShiro.Protocol;
|
||||
|
||||
public enum ParamType
|
||||
{
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using Fleet.Core;
|
||||
|
||||
namespace Monitor.Protocol;
|
||||
namespace MoShiro.Protocol;
|
||||
|
||||
[JsonConverter(typeof(ProbeIdJsonConverter))]
|
||||
public readonly record struct ProbeId(string Value)
|
||||
+5
-5
@@ -7,7 +7,7 @@
|
||||
<ProjectReference Include="..\..\fleet\src\Fleet.Rpc\Fleet.Rpc.csproj" />
|
||||
</ItemGroup>
|
||||
<!--
|
||||
构建信息:版本来自 $(Version),tag、提交、构建时间来自环境变量 MONITOR_TAG / MONITOR_COMMIT / MONITOR_BUILT_AT
|
||||
构建信息:版本来自 $(Version),tag、提交、构建时间来自环境变量 MOSHIRO_TAG / MOSHIRO_COMMIT / MOSHIRO_BUILT_AT
|
||||
(scripts/publish.sh 和 CI 会设置;本地开发不设置就是空,这样本地构建是可重复的、不会每次都重新编译)。
|
||||
生成一个带常量的源文件,NativeAOT 下不用反射。
|
||||
-->
|
||||
@@ -16,14 +16,14 @@
|
||||
<BuildInfoFile>$(IntermediateOutputPath)BuildInfo.g.cs</BuildInfoFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<BuildInfoLine Include="namespace Monitor.Protocol%3B" />
|
||||
<BuildInfoLine Include="namespace MoShiro.Protocol%3B" />
|
||||
<BuildInfoLine Include="/// <summary>这个程序是什么时候、从哪个版本构建出来的(构建时生成)。</summary>" />
|
||||
<BuildInfoLine Include="public static class BuildInfo" />
|
||||
<BuildInfoLine Include="{" />
|
||||
<BuildInfoLine Include=" public const string Version = "$(Version)"%3B" />
|
||||
<BuildInfoLine Include=" public const string Tag = "$(MONITOR_TAG)"%3B" />
|
||||
<BuildInfoLine Include=" public const string Commit = "$(MONITOR_COMMIT)"%3B" />
|
||||
<BuildInfoLine Include=" public const string BuiltAt = "$(MONITOR_BUILT_AT)"%3B" />
|
||||
<BuildInfoLine Include=" public const string Tag = "$(MOSHIRO_TAG)"%3B" />
|
||||
<BuildInfoLine Include=" public const string Commit = "$(MOSHIRO_COMMIT)"%3B" />
|
||||
<BuildInfoLine Include=" public const string BuiltAt = "$(MOSHIRO_BUILT_AT)"%3B" />
|
||||
<BuildInfoLine Include="}" />
|
||||
</ItemGroup>
|
||||
<WriteLinesToFile File="$(BuildInfoFile)" Lines="@(BuildInfoLine)" Overwrite="true" WriteOnlyWhenDifferent="true" />
|
||||
+3
-3
@@ -1,9 +1,9 @@
|
||||
using Fleet.Core;
|
||||
|
||||
namespace Monitor.Protocol;
|
||||
namespace MoShiro.Protocol;
|
||||
|
||||
/// <summary>Monitor 的错误码(在 Fleet 错误码之上扩展)。REST、JSON-RPC、OpenAPI 共用同一份。</summary>
|
||||
public static class MonitorErrors
|
||||
/// <summary>MoShiro 的错误码(在 Fleet 错误码之上扩展)。REST、JSON-RPC、OpenAPI 共用同一份。</summary>
|
||||
public static class MoShiroErrors
|
||||
{
|
||||
public static readonly ErrorCode ValidationFailed = new("validation_failed");
|
||||
public static readonly ErrorCode BudgetExceeded = new("budget_exceeded");
|
||||
+7
-7
@@ -1,4 +1,4 @@
|
||||
namespace Monitor.Protocol;
|
||||
namespace MoShiro.Protocol;
|
||||
|
||||
public static class ProtocolVersion
|
||||
{
|
||||
@@ -25,8 +25,8 @@ public static class ProtocolLimits
|
||||
public const long MaxLineBudgetBitsPerSecond = 100_000;
|
||||
}
|
||||
|
||||
/// <summary>二进制通道号(0–15 属于 Fleet,Monitor 从 16 开始)。</summary>
|
||||
public static class MonitorChannels
|
||||
/// <summary>二进制通道号(0–15 属于 Fleet,MoShiro 从 16 开始)。</summary>
|
||||
public static class MoShiroChannels
|
||||
{
|
||||
/// <summary>Agent → Backend:RawChunk(发件箱)。</summary>
|
||||
public const byte RawChunk = 16;
|
||||
@@ -35,9 +35,9 @@ public static class MonitorChannels
|
||||
public const byte ColumnBlock = 17;
|
||||
}
|
||||
|
||||
public static class MonitorCapabilities
|
||||
public static class MoShiroCapabilities
|
||||
{
|
||||
public const string Base = "monitor.v1";
|
||||
public const string KindsPrefix = "monitor.kinds:";
|
||||
public const string BlocksPrefix = "monitor.blocks:";
|
||||
public const string Base = "moshiro.v1";
|
||||
public const string KindsPrefix = "moshiro.kinds:";
|
||||
public const string BlocksPrefix = "moshiro.blocks:";
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
namespace Monitor.Protocol;
|
||||
namespace MoShiro.Protocol;
|
||||
|
||||
/// <summary>CRC-32C(Castagnoli),RawChunk 的完整性校验。</summary>
|
||||
public static class Crc32c
|
||||
+1
-1
@@ -2,7 +2,7 @@ using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Fleet.Core;
|
||||
|
||||
namespace Monitor.Protocol;
|
||||
namespace MoShiro.Protocol;
|
||||
|
||||
/// <summary>Agent 单调时钟与 UTC 的锚点,以及 Probe 时钟相对 Agent 时钟的偏移估计。</summary>
|
||||
public sealed class ChunkClock
|
||||
+6
-6
@@ -3,18 +3,18 @@ using System.IO.Compression;
|
||||
using System.Text.Json;
|
||||
using Fleet.Core;
|
||||
|
||||
namespace Monitor.Protocol;
|
||||
namespace MoShiro.Protocol;
|
||||
|
||||
/// <summary>
|
||||
/// RawChunk 的编解码(Probe、Agent、Backend、离线工具共用同一份代码)。
|
||||
/// 布局:<c>"MNRC" | u8 container_version | u32 crc32c(压缩数据) | Brotli( u32 header_len | header JSON | 各列数据 )</c>。
|
||||
/// 布局:<c>"MSRC" | u8 container_version | u32 crc32c(压缩数据) | Brotli( u32 header_len | header JSON | 各列数据 )</c>。
|
||||
/// 列数据:可空列先写有效位图,再写有效值;plain 为无符号 varint(有符号类型用 zigzag),delta 为与上一个有效值之差的 zigzag varint。
|
||||
/// </summary>
|
||||
public static class RawChunkCodec
|
||||
{
|
||||
private const int PrefixBytes = 4 + 1 + 4;
|
||||
|
||||
private static ReadOnlySpan<byte> Magic => "MNRC"u8;
|
||||
private static ReadOnlySpan<byte> Magic => "MSRC"u8;
|
||||
|
||||
/// <summary>压缩之前的正文:<c>u32 header_len | header JSON | 各列数据</c>。布局变化时黄金字节测试会失败,提醒升级版本。</summary>
|
||||
public static byte[] EncodeBody(RawChunk chunk)
|
||||
@@ -40,7 +40,7 @@ public static class RawChunkCodec
|
||||
header.Streams.Add(streamHeader);
|
||||
}
|
||||
|
||||
byte[] headerJson = JsonSerializer.SerializeToUtf8Bytes(header, MonitorJsonContext.Default.RawChunkHeader);
|
||||
byte[] headerJson = JsonSerializer.SerializeToUtf8Bytes(header, MoShiroJsonContext.Default.RawChunkHeader);
|
||||
|
||||
using var body = new MemoryStream();
|
||||
Span<byte> length = stackalloc byte[4];
|
||||
@@ -114,7 +114,7 @@ public static class RawChunkCodec
|
||||
RawChunkHeader? header;
|
||||
try
|
||||
{
|
||||
header = JsonSerializer.Deserialize(plain.AsSpan(4, (int)headerLength), MonitorJsonContext.Default.RawChunkHeader);
|
||||
header = JsonSerializer.Deserialize(plain.AsSpan(4, (int)headerLength), MoShiroJsonContext.Default.RawChunkHeader);
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
@@ -159,7 +159,7 @@ public static class RawChunkCodec
|
||||
}
|
||||
|
||||
private static Result<RawChunk> Corrupt(string message) =>
|
||||
Result<RawChunk>.Fail(MonitorErrors.RawCorrupt, message);
|
||||
Result<RawChunk>.Fail(MoShiroErrors.RawCorrupt, message);
|
||||
|
||||
private static byte[]? Inflate(ReadOnlySpan<byte> payload)
|
||||
{
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
namespace Monitor.Protocol;
|
||||
namespace MoShiro.Protocol;
|
||||
|
||||
/// <summary>按 <see cref="StreamSpec"/> 逐行构造一个 <see cref="RawStream"/>(用于测试、模拟器和离线工具,不用于节点热路径)。</summary>
|
||||
public sealed class StreamBuilder
|
||||
+19
-19
@@ -2,25 +2,25 @@ using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Fleet.Core;
|
||||
|
||||
namespace Monitor.Protocol;
|
||||
namespace MoShiro.Protocol;
|
||||
|
||||
/// <summary>monitor.* 方法名。新增方法 = 在这里定义名称和 params/result,再在组装处加一行 <c>.On(...)</c>。</summary>
|
||||
public static class MonitorMethods
|
||||
/// <summary>moshiro.* 方法名。新增方法 = 在这里定义名称和 params/result,再在组装处加一行 <c>.On(...)</c>。</summary>
|
||||
public static class MoShiroMethods
|
||||
{
|
||||
public const string TestRun = "monitor.test.run";
|
||||
public const string TestCancel = "monitor.test.cancel";
|
||||
public const string ProbeDisconnect = "monitor.probe.disconnect";
|
||||
public const string TestStatus = "monitor.test.status";
|
||||
public const string Event = "monitor.event";
|
||||
public const string Host = "monitor.host";
|
||||
public const string UpdateOffer = "monitor.update.offer";
|
||||
public const string UpdateApply = "monitor.update.apply";
|
||||
public const string TestRun = "moshiro.test.run";
|
||||
public const string TestCancel = "moshiro.test.cancel";
|
||||
public const string ProbeDisconnect = "moshiro.probe.disconnect";
|
||||
public const string TestStatus = "moshiro.test.status";
|
||||
public const string Event = "moshiro.event";
|
||||
public const string Host = "moshiro.host";
|
||||
public const string UpdateOffer = "moshiro.update.offer";
|
||||
public const string UpdateApply = "moshiro.update.apply";
|
||||
|
||||
// Probe ↔ Agent(点对点会话)
|
||||
public const string Clock = "monitor.clock";
|
||||
public const string TestPhase = "monitor.test.phase";
|
||||
public const string TestPhaseEnd = "monitor.test.phase_end";
|
||||
public const string TestAbort = "monitor.test.abort";
|
||||
public const string Clock = "moshiro.clock";
|
||||
public const string TestPhase = "moshiro.test.phase";
|
||||
public const string TestPhaseEnd = "moshiro.test.phase_end";
|
||||
public const string TestAbort = "moshiro.test.abort";
|
||||
}
|
||||
|
||||
public static class AgentEventKinds
|
||||
@@ -159,7 +159,7 @@ public sealed class ProbeAgentList
|
||||
public List<AgentEndpoint> Agents { get; set; } = [];
|
||||
}
|
||||
|
||||
/// <summary>注册元数据(Monitor 定义,经 Fleet 的 <c>meta</c> 字段带上来)。</summary>
|
||||
/// <summary>注册元数据(MoShiro 定义,经 Fleet 的 <c>meta</c> 字段带上来)。</summary>
|
||||
public sealed class AgentEnrollMeta
|
||||
{
|
||||
[JsonPropertyName("probe_tcp_port")]
|
||||
@@ -220,7 +220,7 @@ public sealed class PlatformInfo
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 面板给节点的更新清单(<c>monitor.update.offer</c>):<c>manifest</c> 是发布清单的原始文本,<c>signature</c> 是 base64 的签名。
|
||||
/// 面板给节点的更新清单(<c>moshiro.update.offer</c>):<c>manifest</c> 是发布清单的原始文本,<c>signature</c> 是 base64 的签名。
|
||||
/// 节点只是把它们原样放进数据目录;验签、拉取、重启都由宿主机上的更新器完成(节点进程不执行任何命令,也不信任清单的内容)。
|
||||
/// </summary>
|
||||
public sealed class UpdateOfferParams
|
||||
@@ -436,7 +436,7 @@ public sealed class LineTaskSet
|
||||
public List<int> TcpPorts { get; set; } = [];
|
||||
}
|
||||
|
||||
/// <summary><c>monitor.clock</c>:Probe 用它估计与 Agent 单调时钟的偏移(对称往返假设)。</summary>
|
||||
/// <summary><c>moshiro.clock</c>:Probe 用它估计与 Agent 单调时钟的偏移(对称往返假设)。</summary>
|
||||
public sealed class ClockParams
|
||||
{
|
||||
[JsonPropertyName("probe_mono_us")]
|
||||
@@ -543,4 +543,4 @@ public static class FragmentKeys
|
||||
[JsonSerializable(typeof(AgentHelloMeta))]
|
||||
[JsonSerializable(typeof(AgentHeartbeatExtra))]
|
||||
[JsonSerializable(typeof(RawChunkHeader))]
|
||||
public sealed partial class MonitorJsonContext : JsonSerializerContext;
|
||||
public sealed partial class MoShiroJsonContext : JsonSerializerContext;
|
||||
+3
-3
@@ -3,7 +3,7 @@ using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Fleet.Core;
|
||||
|
||||
namespace Monitor.Protocol;
|
||||
namespace MoShiro.Protocol;
|
||||
|
||||
/// <summary>Task = { id, scope, kind, target, params, schedule, enabled }。参数已经按 ParamSpec 校验并补全默认值。</summary>
|
||||
public sealed class TaskSpec
|
||||
@@ -79,9 +79,9 @@ public static class TaskSchedule
|
||||
{
|
||||
return minutes >= 60
|
||||
? Result<int?>.Ok(minutes)
|
||||
: Result<int?>.Fail(MonitorErrors.ValidationFailed, "every:N requires N >= 60 minutes");
|
||||
: Result<int?>.Fail(MoShiroErrors.ValidationFailed, "every:N requires N >= 60 minutes");
|
||||
}
|
||||
|
||||
return Result<int?>.Fail(MonitorErrors.ValidationFailed, "schedule must be continuous, once or every:<minutes>");
|
||||
return Result<int?>.Fail(MoShiroErrors.ValidationFailed, "schedule must be continuous, once or every:<minutes>");
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -2,7 +2,7 @@ using System.Buffers.Binary;
|
||||
using System.Security.Cryptography;
|
||||
using Fleet.Core;
|
||||
|
||||
namespace Monitor.Protocol;
|
||||
namespace MoShiro.Protocol;
|
||||
|
||||
/// <summary>
|
||||
/// 数据面的 TCP 连接(Fleet 之外的线格式)。连接都由 Probe 发起;TLS 是可选的(ClientHello 以 0x16 开头,
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
using System.Buffers.Binary;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Monitor.Protocol;
|
||||
namespace MoShiro.Protocol;
|
||||
|
||||
public enum UdpPacketType : byte
|
||||
{
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
using System.Text.Json;
|
||||
using Fleet.Core;
|
||||
using Monitor.Protocol;
|
||||
using MoShiro.Protocol;
|
||||
|
||||
namespace Monitor.Measurement.Tests;
|
||||
namespace MoShiro.Measurement.Tests;
|
||||
|
||||
public sealed class MeasurementTests
|
||||
{
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="xunit.v3" />
|
||||
<ProjectReference Include="..\..\Monitor.Measurement\Monitor.Measurement.csproj" />
|
||||
<ProjectReference Include="..\..\MoShiro.Measurement\MoShiro.Measurement.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Using Include="Xunit" />
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
namespace Monitor.Measurement.Tests;
|
||||
namespace MoShiro.Measurement.Tests;
|
||||
|
||||
public sealed class PlatformDetectorTests
|
||||
{
|
||||
+6
-6
@@ -1,8 +1,8 @@
|
||||
using System.Text.Json;
|
||||
using Fleet.Core;
|
||||
using Monitor.Protocol;
|
||||
using MoShiro.Protocol;
|
||||
|
||||
namespace Monitor.Protocol.Tests;
|
||||
namespace MoShiro.Protocol.Tests;
|
||||
|
||||
public sealed class CatalogTests
|
||||
{
|
||||
@@ -101,8 +101,8 @@ public sealed class CatalogTests
|
||||
Tasks = [new TaskSpec { Id = new TaskId("tsk_1"), Kind = "udp_echo", Params = new Dictionary<string, JsonElement> { ["rate_hz"] = Json("10") } }],
|
||||
Peers = [new PeerSpec { ProbeId = new ProbeId("prb_1"), PublicKey = "AAAA" }],
|
||||
};
|
||||
string text = JsonSerializer.Serialize(set, MonitorJsonContext.Default.TaskSet);
|
||||
TaskSet back = JsonSerializer.Deserialize(text, MonitorJsonContext.Default.TaskSet)!;
|
||||
string text = JsonSerializer.Serialize(set, MoShiroJsonContext.Default.TaskSet);
|
||||
TaskSet back = JsonSerializer.Deserialize(text, MoShiroJsonContext.Default.TaskSet)!;
|
||||
|
||||
Assert.Contains("\"id\":\"tsk_1\"", text);
|
||||
Assert.Equal(7, back.Version);
|
||||
@@ -114,7 +114,7 @@ public sealed class CatalogTests
|
||||
[Fact]
|
||||
public void AgentEnrollMeta_ToleratesUnknownFields_AndKeepsDefaults()
|
||||
{
|
||||
AgentEnrollMeta meta = JsonSerializer.Deserialize("{\"kinds\":[\"udp_echo\"],\"future\":1}", MonitorJsonContext.Default.AgentEnrollMeta)!;
|
||||
AgentEnrollMeta meta = JsonSerializer.Deserialize("{\"kinds\":[\"udp_echo\"],\"future\":1}", MoShiroJsonContext.Default.AgentEnrollMeta)!;
|
||||
Assert.Equal(7443, meta.ProbeTcpPort);
|
||||
Assert.Equal(["udp_echo"], meta.Kinds);
|
||||
}
|
||||
@@ -122,7 +122,7 @@ public sealed class CatalogTests
|
||||
[Fact]
|
||||
public void ErrorCodes_AreSnakeCase()
|
||||
{
|
||||
foreach (System.Reflection.FieldInfo field in typeof(MonitorErrors).GetFields())
|
||||
foreach (System.Reflection.FieldInfo field in typeof(MoShiroErrors).GetFields())
|
||||
{
|
||||
string value = ((ErrorCode)field.GetValue(null)!).Value;
|
||||
Assert.Matches("^[a-z]+(_[a-z]+)*$", value);
|
||||
+2
-2
@@ -5,8 +5,8 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="xunit.v3" />
|
||||
<ProjectReference Include="..\..\Monitor.Protocol\Monitor.Protocol.csproj" />
|
||||
<ProjectReference Include="..\..\..\tests\Monitor.TestSupport\Monitor.TestSupport.csproj" />
|
||||
<ProjectReference Include="..\..\MoShiro.Protocol\MoShiro.Protocol.csproj" />
|
||||
<ProjectReference Include="..\..\..\tests\MoShiro.TestSupport\MoShiro.TestSupport.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Using Include="Xunit" />
|
||||
+5
-5
@@ -1,10 +1,10 @@
|
||||
using System.Buffers.Binary;
|
||||
using System.IO.Compression;
|
||||
using Fleet.Core;
|
||||
using Monitor.Protocol;
|
||||
using Monitor.TestSupport;
|
||||
using MoShiro.Protocol;
|
||||
using MoShiro.TestSupport;
|
||||
|
||||
namespace Monitor.Protocol.Tests;
|
||||
namespace MoShiro.Protocol.Tests;
|
||||
|
||||
public sealed class RawChunkCodecTests
|
||||
{
|
||||
@@ -103,7 +103,7 @@ public sealed class RawChunkCodecTests
|
||||
byte[] badCrc = (byte[])good.Clone();
|
||||
badCrc[^1] ^= 0xFF;
|
||||
|
||||
Assert.Equal(MonitorErrors.RawCorrupt, RawChunkCodec.Decode(badMagic).Error.Code);
|
||||
Assert.Equal(MoShiroErrors.RawCorrupt, RawChunkCodec.Decode(badMagic).Error.Code);
|
||||
Assert.Contains("version", RawChunkCodec.Decode(badVersion).Error.Message);
|
||||
Assert.Contains("crc", RawChunkCodec.Decode(badCrc).Error.Message);
|
||||
Assert.False(RawChunkCodec.Decode(good.AsSpan(0, good.Length / 2)).IsSuccess);
|
||||
@@ -190,7 +190,7 @@ public sealed class RawChunkCodecTests
|
||||
private static byte[] Wrap(byte[] payload)
|
||||
{
|
||||
byte[] result = new byte[9 + payload.Length];
|
||||
"MNRC"u8.CopyTo(result);
|
||||
"MSRC"u8.CopyTo(result);
|
||||
result[4] = ProtocolVersion.Container;
|
||||
BinaryPrimitives.WriteUInt32LittleEndian(result.AsSpan(5), Crc32c.Compute(payload));
|
||||
payload.CopyTo(result, 9);
|
||||
Reference in new issue
Block a user