Push a live signal to clients when news posts are published#1348
Open
2Pacalypse- wants to merge 2 commits into
Open
Push a live signal to clients when news posts are published#13482Pacalypse- wants to merge 2 commits into
2Pacalypse- wants to merge 2 commits into
Conversation
|
gg, ship it |
bb3e821 to
be58653
Compare
5ed7d30 to
7dab94d
Compare
|
gg, ship it |
The Node server now consumes the newsPostsChanged Redis message: it tracks the latest published post, publishes a newsPostChange event on a new /newsPosts socket path when that changes, seeds newly-connected clients with current state, and keeps a timer armed for the next scheduled publish so scheduled posts emit the signal when they go live without any mutation firing. Clients track a per-user last-seen post and light the Home nav pip (shared with the urgent-message indicator) when an unseen post is published; visiting the home page marks it seen. Clock gains clearTimeout (with a FakeClock override that removes the scheduled entry) so the reconcile timer can be re-armed safely.
A DB error during a reconcile pass (or while querying the next scheduled publish time) previously just returned — if that pass had been triggered by the scheduled-publish timer, the timer was already cleared and scheduled publishing stalled until the next post mutation. Failed passes now arm a 60s retry timer instead.
7dab94d to
af42bfe
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fourth PR of the dynamic news stack (on top of #1347). Publishing a news post now lights an unread pip on the Home nav entry for connected clients in real time — including posts that go live on a schedule.
Changes
NewsService: consumes thenewsPostsChangedRedis message the Rust side publishes on every post mutation. It reconciles the latest published post, publishes anewsPostChangeevent on a new/newsPostssocket path only when the(id, publishedAt)pair actually changes (a cleared variant when nothing is published), and seeds newly-connected clients with the current state. Reconcile passes are serialized (chained promises) so overlapping Redis messages can't complete out of order and cache stale state.published_at(generation-guarded against re-arms, clamped to the 32-bit setTimeout max with re-arming, +1s slop past the boundary), so a scheduled post pushes the signal the moment it goes live with no mutation involved.Clock.clearTimeoutadded to the clock abstraction with a realFakeClockoverride (which also fixes FakeClock returning ids that were never attached to its queue entries).newsPostChangeevents feed alatestNewsPostIdatom; a per-usernews.lastSeenNewsPost(localStorage) drivesuseHasNewNewsPost(), which joinsuseHasNewUrgentMessage()on the Home nav pip in the app bar. Rendering the home news feed marks the newest post seen./newsPostspath (rather than reusing/news) because socket-group subscriptions deliver exactly one initial-data payload per path — urgent-message state and post state each need their own seed.Verification
Two live browser clients against the dev stack: a viewer's pip lit ~2s after an admin published a new post (viewer parked on another page, no reload); visiting home marked it seen and cleared the pip; republishing an already-seen post correctly did not relight it (id-based semantics); creating a scheduled post did not light the pip, and the pip then lit within seconds of the scheduled minute passing, driven purely by the service timer. Wire-level check confirmed the
/newsPostsseed payload on socket connect.lint,typecheck, full unit suite (870) clean.