fix(api): refresh node build versions from heartbeat [CI]
ci/woodpecker/push/web-build Pipeline was successful
ci/woodpecker/push/verify Pipeline was successful
ci/woodpecker/push/dev-image Pipeline was successful

This commit is contained in:
justme committed 2026-10-12 01:57:50 +08:00
1 parent fe049c97fa
commit 52059b04c1
2 files changed
+28

No files matched your search

@@ -118,6 +118,7 @@ public sealed class MoShiroNodeEventSink : INodeEventSink
await ApplyHelloAsync(id, hello, ct);
break;
case NodeEventKind.Heartbeat when nodeEvent.Extra is { } extra:
await _nodes.SetVersionAsync(id.Value, NodeKinds.Agent, nodeEvent.Node.NodeVersion, ct);
try
{
AgentRuntimeState state = _runtime.Get(id);
@@ -172,6 +173,8 @@ public sealed class MoShiroNodeEventSink : INodeEventSink
}
}
await _nodes.SetVersionAsync(id.Value, NodeKinds.Probe, nodeEvent.Node.NodeVersion, ct);
await _releases.OfferToNodeAsync(id, ct);
await _schedule.SendToNodeAsync(id, ct);
break;
@@ -182,6 +185,7 @@ public sealed class MoShiroNodeEventSink : INodeEventSink
_quicRuntime.MarkProbeOffline(id.Value, nodeEvent.AtMs);
break;
case NodeEventKind.Heartbeat when nodeEvent.Extra is { } extra:
await _nodes.SetVersionAsync(id.Value, NodeKinds.Probe, nodeEvent.Node.NodeVersion, ct);
try
{
ProbeHeartbeatExtra? heartbeat = extra.Deserialize(MoShiroJsonContext.Default.ProbeHeartbeatExtra);
@@ -254,6 +258,11 @@ public sealed class MoShiroNodeEventSink : INodeEventSink
}
_owners.Report(id.Value, meta.Owners);
if (meta.Platform is { } platform)
{
platform.Version = hello.NodeVersion;
}
await _nodes.SetVersionAsync(id.Value, NodeKinds.Agent, hello.NodeVersion, ct);
AgentRecord? before = await _agents.GetAsync(id, ct);
string? limitsJson = meta.LocalLimits is null ? null : JsonSerializer.Serialize(meta.LocalLimits, LocalLimitsJson.Default.LocalLimits);
string? ipv6Json = meta.Ipv6 is null ? null : JsonSerializer.Serialize(meta.Ipv6, MoShiroJsonContext.Default.Ipv6Diagnostic);
@@ -93,6 +93,25 @@ public sealed class NodeInfoService
await SaveAsync(current with { Info = i with { Os = os, OsName = name, Arch = arch, Version = version, Tag = tag, Commit = commit, BuiltAt = builtAt }, UpdatedAtMs = Now() }, ct);
}
/// <summary>Keep the displayed build version aligned with the authenticated Fleet hello, even if platform metadata is absent.</summary>
public async ValueTask SetVersionAsync(string nodeId, string kind, string? version, CancellationToken ct)
{
string? clean = Clean(version, 32);
if (clean is null)
{
return;
}
await EnsureLoadedAsync(ct);
NodeMeta current = _cache.TryGetValue(nodeId, out NodeMeta? found) ? found : Empty(nodeId, kind);
if (current.Info.Version == clean)
{
return;
}
await SaveAsync(current with { Info = current.Info with { Version = clean }, UpdatedAtMs = Now() }, ct);
}
/// <summary>
/// 节点从某个地址连上来了:查一次它的国家和运营商。已经查过同一个地址(并且没过期)就什么也不做;
/// 私有地址不查;查询失败或服务关着,不影响别的,隔一阵再试。