The live feed's depth is a packet count, not a clock
Restores the WIP parked on 2026-08-31 before the PicoCalc sync. The feed seeded itself from `utcnow() - OBSERVATION_WINDOW`, borrowing the two-hour window the dashboard's rolling stats are bounded by. Two bounds for one list, and the wrong one usually won: on a quiet mesh the screen opened nearly empty, not because little had ever been heard but because little had been heard *lately* — which is the one thing the reader can already see from the ages in the rows. So the cap is the only bound, and it goes from 100 to 500. A busy hour runs to some hundreds of packets, so a hundred rows forgot the last ten minutes at exactly the moment the feed was worth watching. Depth is close to free here: the paint is windowed, so the cap costs a pointer per entry and a few milliseconds at open, never anything per frame. Widening the seed costs nothing either — `observed_at` is indexed, so the query walks the index backwards and stops after _FEED_CAP rows whatever the floor. Measured on a 700-packet history spread over a year: the unbounded seed fills all 500 rows and reaches 249 days back, where the two-hour window seeded one. OBSERVATION_WINDOW keeps its name and its meaning, now solely the dashboard's: it is what the RF health card means by "reception over 2 h", and its docstring says so rather than leaving the next reader to find two screens sharing it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
026e78078e
commit
2baa8e1bfc
2 files changed
+34
-12
No files matched your search
@@ -33,10 +33,13 @@ if TYPE_CHECKING:
|
||||
from ..core.contact_score import ContactSignals
|
||||
|
||||
|
||||
#: The trailing window the dashboard's live observation stats and packet feed prune to
|
||||
#: — "what's happening right now" territory, labelled "reception over 2 h" on the RF
|
||||
#: health card. Distinct from the deeper channel-activity window below: this bounds a
|
||||
#: live view, that one only feeds a scaling peak.
|
||||
#: The trailing window the dashboard's live observation stats prune to — "what's
|
||||
#: happening right now" territory, labelled "reception over 2 h" on the RF health card.
|
||||
#: Distinct from the deeper channel-activity window below: this bounds a live view, that
|
||||
#: one only feeds a scaling peak. The Live feed screen once shared it and no longer does:
|
||||
#: its depth is a packet count, not a duration (see
|
||||
#: :data:`~meshterm.ui.livefeed_screen._FEED_SEED_FLOOR`), so this number means the
|
||||
#: dashboard's two hours and nothing else.
|
||||
OBSERVATION_WINDOW = timedelta(hours=2)
|
||||
|
||||
#: The trailing window a channel's activity histogram is computed over. Six hours is
|
||||
|
||||
@@ -47,6 +47,7 @@ from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from collections import deque
|
||||
from datetime import datetime, timezone
|
||||
from typing import TYPE_CHECKING, Any, Mapping, Optional, Sequence
|
||||
|
||||
from rich.text import Text
|
||||
@@ -55,7 +56,6 @@ from ..core.channels import identify_channel, split_channel_sender
|
||||
from ..core.events import EventKind, MeshEvent
|
||||
from ..core.frames import CHANNEL_CLASSES, ENDPOINT_HASH_BYTES
|
||||
from ..core.models import Observation, utcnow
|
||||
from ..persistence.repository import OBSERVATION_WINDOW
|
||||
from .menus import fit_cells
|
||||
from .packet_viewer import (
|
||||
KIND_STYLES,
|
||||
@@ -78,8 +78,29 @@ if TYPE_CHECKING:
|
||||
_REFRESH_S = 1.0
|
||||
|
||||
#: How many feed rows are kept (the feed windows within the screen, so this is
|
||||
#: history depth, not layout).
|
||||
_FEED_CAP = 100
|
||||
#: history depth, not layout) — and, being the feed's *only* bound, the one number that
|
||||
#: decides how far back the screen remembers. A busy hour on a real mesh runs to some
|
||||
#: hundreds of packets, so a hundred rows forgot the last ten minutes exactly when the
|
||||
#: feed was worth watching. Depth is nearly free here: the paint is windowed
|
||||
#: (:meth:`LiveFeedScreen._feed_lines` formats only the rows on screen), so the cap costs
|
||||
#: a pointer per entry and a few milliseconds of hydration at open, never anything per
|
||||
#: frame.
|
||||
_FEED_CAP = 500
|
||||
|
||||
#: How far back the opening seed may reach: **no limit** — the cap alone says how much
|
||||
#: history the feed holds, and a clock has no business overruling it. A quiet mesh would
|
||||
#: otherwise open a half-empty screen not because nothing was ever heard but because
|
||||
#: nothing was heard *lately*, which is the one thing the reader can already see.
|
||||
#:
|
||||
#: The mechanics are unchanged — :meth:`~meshterm.persistence.repository.Repository
|
||||
#: .recent_observations` still takes a ``since``, and this is simply a floor no stored
|
||||
#: row predates. It stays cheap because ``observed_at`` is indexed: the query walks the
|
||||
#: index backwards and stops after :data:`_FEED_CAP` rows, so widening the window reads
|
||||
#: no more rows than narrowing it did. Deliberately *not*
|
||||
#: :data:`~meshterm.persistence.repository.OBSERVATION_WINDOW`, which the feed used to
|
||||
#: borrow: that one bounds the dashboard's rolling stats and is what its RF health card
|
||||
#: means by "reception over 2 h".
|
||||
_FEED_SEED_FLOOR = datetime.min.replace(tzinfo=timezone.utc)
|
||||
|
||||
#: The feed's fixed subject-lane width; anything longer ellipsizes so the columns hold.
|
||||
#: Sized for a node name, which is what most classes put here — and wide enough that the
|
||||
@@ -826,11 +847,9 @@ async def open_livefeed(ctx: "AppContext") -> None:
|
||||
key_of = trace_runner.make_name_key_resolver(contacts, stored_names)
|
||||
prefix_bytes = await _routing_prefix_bytes(ctx)
|
||||
|
||||
# Only the newest screenful is kept (the deque caps at _FEED_CAP), so only that
|
||||
# many are worth hydrating.
|
||||
seed = ctx.repo.recent_observations(
|
||||
since=utcnow() - OBSERVATION_WINDOW, limit=_FEED_CAP
|
||||
)
|
||||
# The cap is the only bound: the newest _FEED_CAP packets ever recorded, however
|
||||
# long ago the quiet stretch before them began.
|
||||
seed = ctx.repo.recent_observations(since=_FEED_SEED_FLOOR, limit=_FEED_CAP)
|
||||
screen = LiveFeedScreen(
|
||||
session=session,
|
||||
resolve=resolve,
|
||||
|
||||
Reference in new issue
Block a user