diff --git a/backend/src/MoShiro.Backend.Application/Query/QueryService.cs b/backend/src/MoShiro.Backend.Application/Query/QueryService.cs
index c97921f..8bb0b7b 100644
--- a/backend/src/MoShiro.Backend.Application/Query/QueryService.cs
+++ b/backend/src/MoShiro.Backend.Application/Query/QueryService.cs
@@ -23,9 +23,11 @@ public sealed class QueryService
private readonly ITestStore _tests;
private readonly BackendOptions _options;
private readonly TimeProvider _time;
+ private readonly AgentRuntime _runtime;
- public QueryService(RangeResolver resolver, SourcePlanner planner, RowLoader loader, HotLayer hot, IEventStore events, ITestStore tests, BackendOptions options, TimeProvider time)
+ public QueryService(RangeResolver resolver, SourcePlanner planner, RowLoader loader, HotLayer hot, IEventStore events, ITestStore tests, BackendOptions options, TimeProvider time, AgentRuntime runtime)
{
+ _runtime = runtime;
_resolver = resolver;
_planner = planner;
_loader = loader;
@@ -56,11 +58,16 @@ public sealed class QueryService
// ───────────────────────── 单条线路的时序 ─────────────────────────
+ /// 这条线路现在是不是连着(Agent 报告了这个 Probe 的会话):连着的线路窗口以当前时间为终点,不去查“最后一个样本”——Backend 刚重启、热层和持久层还没追上时,后者会落后好几个小时,页面就显示成旧数据。
+ private bool IsConnected(LineKey line) =>
+ _runtime.TryGet(line.Agent, out AgentRuntimeState? state) && state.Probes.Any(p => p.Id == line.Probe.Value && p.IpVersion == line.IpVersion);
+
public async ValueTask> SeriesAsync(LineKey line, RangeRequest request, MetricSelection selection, CancellationToken ct)
{
// anchor=latest:离线或刚恢复的线路,窗口以它最后一个样本为终点(落在最近 5 秒之内就当作在线,仍以当前时间为终点)
if (string.Equals(request.Anchor, "latest", StringComparison.OrdinalIgnoreCase) && request.To is null && request.From is null && request.Range is not null
- && RangeResolver.TryParseSpan(request.Range, out long span))
+ && RangeResolver.TryParseSpan(request.Range, out long span)
+ && !IsConnected(line))
{
long now = _time.GetUtcNow().ToUnixTimeMilliseconds();
if (await _loader.LatestSampleMsAsync(line.Agent, line.Series, now, ct) is { } latest && latest < now - 5000)