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,67 @@
|
||||
using Fleet.Core;
|
||||
using MoShiro.Protocol;
|
||||
|
||||
namespace MoShiro.Backend.Application;
|
||||
|
||||
/// <summary>
|
||||
/// <c>moshiro.host</c>:Agent 每隔几秒上报的主机资源占用快照。最新值放在内存里并实时推给订阅者;每个 Agent 每分钟存一个样本做历史。
|
||||
/// 快照里没有 CPU 型号、主机名、网卡名和 IP(Agent 根本不采集它们)。
|
||||
/// </summary>
|
||||
public sealed class HostStatusService
|
||||
{
|
||||
private static readonly TimeSpan s_stale = TimeSpan.FromSeconds(15);
|
||||
|
||||
private readonly AgentRuntime _runtime;
|
||||
private readonly IHostStore _store;
|
||||
private readonly LiveHub _live;
|
||||
private readonly TimeProvider _time;
|
||||
private readonly Dictionary<NodeId, long> _lastSavedMinute = [];
|
||||
private readonly object _gate = new();
|
||||
|
||||
public HostStatusService(AgentRuntime runtime, IHostStore store, LiveHub live, TimeProvider time)
|
||||
{
|
||||
_runtime = runtime;
|
||||
_store = store;
|
||||
_live = live;
|
||||
_time = time;
|
||||
}
|
||||
|
||||
public async ValueTask OnHostAsync(NodeId agent, HostSnapshot snapshot, CancellationToken ct)
|
||||
{
|
||||
long now = _time.GetUtcNow().ToUnixTimeMilliseconds();
|
||||
snapshot.AtUtcMs = now; // 以 Backend 收到的时间为准:节点的时钟不可信
|
||||
AgentRuntimeState state = _runtime.Get(agent);
|
||||
state.Host = snapshot;
|
||||
state.HostReceivedAtMs = now;
|
||||
_live.Publish(new HostSignal(agent, snapshot));
|
||||
|
||||
long minute = now - (now % 60_000);
|
||||
bool save;
|
||||
lock (_gate)
|
||||
{
|
||||
save = !_lastSavedMinute.TryGetValue(agent, out long last) || last != minute;
|
||||
if (save)
|
||||
{
|
||||
_lastSavedMinute[agent] = minute;
|
||||
}
|
||||
}
|
||||
|
||||
if (save)
|
||||
{
|
||||
await _store.SaveAsync(agent, minute, snapshot, ct);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>最新快照;超过 15 秒没有更新就是过期(Agent 离线或者没有开启上报)。</summary>
|
||||
public (HostSnapshot? Host, bool Stale) Latest(NodeId agent)
|
||||
{
|
||||
if (!_runtime.TryGet(agent, out AgentRuntimeState? state) || state.Host is null)
|
||||
{
|
||||
return (null, true);
|
||||
}
|
||||
|
||||
return (state.Host, _time.GetUtcNow().ToUnixTimeMilliseconds() - state.HostReceivedAtMs > s_stale.TotalMilliseconds);
|
||||
}
|
||||
|
||||
public ValueTask<IReadOnlyList<HostSample>> HistoryAsync(NodeId agent, long fromMs, long toMs, CancellationToken ct) => _store.ReadAsync(agent, fromMs, toMs, ct);
|
||||
}
|
||||
Reference in new issue
Block a user