Skip to content

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

Merged
Joseph Schick (jschick04) merged 1 commit into
mainfrom
jschick/fix-livetail-load-new-events
Jul 23, 2026
Merged

Fix live-tail Load New Events not rendering the new row until reload#665
Joseph Schick (jschick04) merged 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).

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 Outdated
@jschick04
Joseph Schick (jschick04) force-pushed the jschick/fix-livetail-load-new-events branch from 5d4694f to b5858b0 Compare July 23, 2026 22:05
Copilot AI review requested due to automatic review settings July 23, 2026 22:05

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

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

Comment thread src/EventLogExpert.Runtime/EventLog/LogReloadEffects.cs
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. Check the raw store for the log before filtering,
so a concurrently-closed log is skipped without running (or throwing from) the
filter.

Make new-event buffering atomic to close a flush race. Buffering now happens in
a ReduceAddEvent reducer that prepends against the current state, and a completed
flush consumes only its captured snapshot by reference identity
(NewEventBufferConsumedAction) rather than clearing the whole buffer. This keeps
an event a watcher buffers during a flush from being dropped or from resurrecting
an already-flushed event, and removes the old whole-buffer EventBufferedAction.

Replace the inline-ingest test mocks that masked the bug with a queue-faithful
drain harness, and add regression, interleaving, resurrection-ordering,
clear-on-throw, and reference-identity coverage.
Copilot AI review requested due to automatic review settings July 23, 2026 22:27
@jschick04
Joseph Schick (jschick04) force-pushed the jschick/fix-livetail-load-new-events branch from b5858b0 to 9475d99 Compare July 23, 2026 22:27

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

Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.

@jschick04
Joseph Schick (jschick04) marked this pull request as ready for review July 23, 2026 22:39
@jschick04
Joseph Schick (jschick04) requested a review from a team as a code owner July 23, 2026 22:39

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🍆

@jschick04
Joseph Schick (jschick04) merged commit 074cdf8 into main Jul 23, 2026
8 checks passed
@jschick04
Joseph Schick (jschick04) deleted the jschick/fix-livetail-load-new-events branch July 23, 2026 22:45
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.

3 participants