Skip to content

One shared recent-events list per console tab #917

Closed

Description

@V3RON

Part of #905.

Scope

The last hour of events is read once per tab and shared by the Inbox drawer and the lease drawer, instead of once by each. The shared list is kept for 60 s after the last place using it closes, then dropped. Activity keeps its own list and scroll-back as today, which is already dropped the moment the operator leaves Activity.

In short

Opening the Inbox, then a lease's drawer, makes one GET /v1/events?since=1h instead of two, and coming back within a minute makes none. Nothing the operator sees changes.

flowchart LR
  S[stream] --> R["shared recent feed (new, one per tab)"]
  R --> I[Inbox drawer] & L[lease drawer]
  S --> A["Activity's own feed (unchanged)"]
Loading

If it goes wrong: a drawer misses events that arrived while no page used the list.

Technical spec

Facts

# Fact Source
F1 Each screen that reads events builds its own EventFeed (useEventFeed), which reads since=1h on start, merges the stream by event id, reads the gap after a reconnect, and ignores stream events while inactive. ui/src/state/events.ts:36-56; ui/src/data/event-feed.ts:56-140
F2 Users of the recent list: Inbox (state/inbox.ts:91), lease drawer (state/leases.ts:154), worker Events tab (state/workers.ts:186); Activity uses its own feed with history (state/events.ts:82). as cited
F3 A refused recent read is shown, not retried; a network failure is retried 1, 2, 4, 8 s, then every 10 s. ui/src/data/event-feed.ts:121-128
F4 LiveProvider holds the per-tab connection and ticker. ui/src/state/live.tsx:39-60

Modules touched

ui/src/state/live.tsx (the provider holds one shared EventFeed, started at its first user and stopped and dropped 60 s after its last), ui/src/state/events.ts (useRecentEvents uses the shared feed; useEvents keeps its own), ui/src/data/event-feed.ts (only if a stop hook is missing), ui/src/state/inbox.ts, ui/src/state/leases.ts (unchanged calls; listed because their reads change), tests. The shared feed is not a query key: it is filled by the stream and its own reads, as today. Searches: useRecentEvents(, new EventFeed(, useEventFeed(.

Contract and event changes

None.

Other code on the same state

  • While the shared feed is kept (a user, or within 60 s of the last), it stays active: it holds every streamed event and reads the gap after a reconnect, as F1. After it is dropped, the next user starts a new one with a since=1h read.
  • The worker page's Events tab (state/workers.ts:186) is Console: the worker's Events tab scrolls back through its history #911's: this task does not change it.
  • Activity's feed (state/events.ts:82) is separate and unchanged.
    Searches: streamEvent, streamOpened, onStreamOpened( (4 hits).

Failure modes

Call Outcome What happens Limit, counted from
since=1h read refused shown with the refusal, as F3 —
since=1h read network failure retried as F3 1, 2, 4, 8, then 10 s from the failure
reconnect gap one since=<gap> read merged into the shared list, as F1 —

Rules in play

  • ADR 0013 §2 "Open the stream and hold what it sends": the shared feed holds the stream for as long as it is kept.
  • ADR 0044 §1: the shared list is dropped 60 s after its last user.

Tests

Seam: the state hooks through LiveContext with connect, fakeClock and settle from ui/src/data/live/test-support.ts, as ui/src/state/live.test.tsx uses them.

  • Event lists are shared and bounded: useInbox then useLeaseEvents (each mounted and unmounted) → one since=1h read; a streamed event appears in both once; an event streamed 30 s after the last user left appears when a user comes back at 50 s, with no read; a user at 61 s → a new since=1h read.

Done when

  • pnpm vitest run ui/src passes.
  • e2e/console/inbox.spec.ts and leases.spec.ts pass.

Out of scope

Activity's history; the worker Events tab (#911); the per-second clock (follow-up, see #905 Non-goals).

Depends on

Written by an agent.

Activity

  1. added
    task:draftScope written; technical spec or its spec check missing.
    on Oct 23, 2026
  2. changed the title [-]The console sends ETags back and patches lease renewals in place[/-] [+]One shared recent-events list, bounded history, and a cheaper clock[/+] on Oct 23, 2026
  3. changed the title [-]One shared recent-events list, bounded history, and a cheaper clock[/-] [+]One shared recent-events list per console tab[/+] on Oct 23, 2026
  4. added
    task:readySpec checked. An agent may implement it once its Depends on allow.
    and removed
    task:draftScope written; technical spec or its spec check missing.
    on Oct 23, 2026
  5. self-assigned this
    on Oct 23, 2026
  6. added a commit that references this issue on Oct 23, 2026
    9ef52ca
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

task:readySpec checked. An agent may implement it once its Depends on allow.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions