Skip to content

Fix live-tail Load New Events not rendering the new row until reload#665

Draft
jschick04 wants to merge 1 commit into
mainfrom
jschick/fix-livetail-load-new-events
Draft

Fix live-tail Load New Events not rendering the new row until reload#665
jschick04 wants to merge 1 commit into
mainfrom
jschick/fix-livetail-load-new-events

Conversation

@jschick04

Copy link
Copy Markdown
Collaborator

Problem

Open a log, let the watcher buffer a new event (status bar shows "New Events: 1", continuously-update OFF), then click View > Load New Events. The count clears but the new row does not appear until a full log reload.

Root cause

LogReloadEffects.ProcessNewEventBuffer (and FilteringEffects.HandleAddEvent on the continuously-update path) dispatched IngestRawEventsAction and then read _rawEventStore.Value in the same effect to build the display view. Fluxor 6.10.0 queues nested dispatches, so that read saw the pre-ingest store: the rebuilt view omitted the new event while the buffer count was cleared regardless. A full reload worked only because it uses reducer-before-effect ordering.

Fix

  • New effect-only RebuildDisplayViewsAction(NewEventsByLog, ClearNewEventBuffer).
  • Both producers now dispatch IngestRawEventsAction then RebuildDisplayViewsAction. Fluxor drains the ingest reducer before the new HandleRebuildDisplayViews effect runs, so the rebuild reads the post-ingest store.
  • The continuation owns the new-event buffer clear and fires it only after a successful rebuild (preserved on throw; a legitimately empty / all-filtered rebuild still clears).
  • Also removes the one-event lag on the continuously-update live-tail path.

Tests

  • Replaced three inline-ingest test mocks that masked the bug with a queue-faithful drain harness (CaptureDispatchQueue + DrainDispatchQueueAsync) that applies the ingest reducer only during drain, so a same-effect pre-ingest read fails the assertions.
  • Added regression (row appears after load), two-event interleaving (both concurrent events survive), and clear-on-throw (buffer preserved on rebuild failure) coverage.
  • Build clean; EventLogExpert.Runtime.Tests 2020/2020 green.

Notes

  • Live-tail single-append now routes through AppendTableEventsBatchAction, which clears the log's PerLogListVersion entry. Verified display-inert (no production consumer).

LogReloadEffects.ProcessNewEventBuffer and FilteringEffects.HandleAddEvent
dispatched IngestRawEventsAction and then read _rawEventStore.Value in the same
effect to build the display view. Fluxor 6.10.0 queues nested dispatches, so
that read saw the pre-ingest store: the rebuilt view omitted the new event
while the buffer count was cleared regardless. The row only appeared after a
full reload, which uses reducer-before-effect ordering.

Move the display rebuild into a dedicated continuation effect,
HandleRebuildDisplayViews, keyed off a new effect-only RebuildDisplayViewsAction.
Both producers now dispatch IngestRawEventsAction then RebuildDisplayViewsAction;
Fluxor drains the ingest reducer before the continuation runs, so the rebuild
reads the post-ingest store. The continuation owns the new-event buffer clear
and fires it only after a successful rebuild (preserved on throw; a legitimately
empty rebuild still clears). This also removes the one-event lag on the
continuously-update live-tail path.

Replace the three inline-ingest test mocks that masked the bug with a
queue-faithful drain harness (CaptureDispatchQueue + DrainDispatchQueueAsync)
that applies the ingest reducer only during drain, and add regression,
two-event interleaving, and clear-on-throw coverage.
Copilot AI review requested due to automatic review settings July 23, 2026 18:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a Fluxor nested-dispatch ordering issue where “Load New Events” (and continuously-update live tail) would clear the new-event counter but not render the newly ingested rows until a full reload, by separating “ingest raw events” from “rebuild display views” into distinct queued actions/effects.

Changes:

  • Introduces RebuildDisplayViewsAction and a new HandleRebuildDisplayViews effect that rebuilds views after raw ingest reducers have applied.
  • Updates the live-tail and buffered “Load New Events” producers to dispatch IngestRawEventsAction followed by RebuildDisplayViewsAction, with buffer clearing moved to the continuation.
  • Refactors/adds tests to simulate Fluxor’s queued nested-dispatch behavior and adds regressions for ordering, interleaving, and clear-on-throw behavior.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
tests/Unit/EventLogExpert.Runtime.Tests/EventLog/EffectsTests.cs Updates/extends tests to be queue-faithful and adds regressions for the stale-read/live-tail lag scenario.
src/EventLogExpert.Runtime/EventLog/RebuildDisplayViewsAction.cs Adds a new internal action to trigger post-ingest display rebuilds.
src/EventLogExpert.Runtime/EventLog/LogReloadEffects.cs Adds HandleRebuildDisplayViews effect and routes buffered “Load New Events” through the new continuation.
src/EventLogExpert.Runtime/EventLog/FilteringEffects.cs Updates continuously-update live-tail path to queue the rebuild action after ingest (no same-effect stale reads).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/EventLogExpert.Runtime/EventLog/LogReloadEffects.cs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants