Skip to content

Auto-refresh requests on SSE ILLDEV-500 - #40

Merged
skomorokh merged 6 commits into
mainfrom
sse-illdev-500
Sep 1, 2026
Merged

Auto-refresh requests on SSE ILLDEV-500#40
skomorokh merged 6 commits into
mainfrom
sse-illdev-500

Conversation

@skomorokh

@skomorokh skomorokh commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

How the UI uses the broker's event stream

The ReShare UI uses the broker's Server-Sent Events endpoint as an invalidation
signal. It does not merge ISO 18626 messages into client state. A frame means
that some cached broker data may be out of date and should be checked again.

This is deliberately a modest use of SSE. The broker remains the source of
truth, React Query remains the cache, and ordinary fetches still produce every
screen the user sees.

One connection for the app

BrokerEventsProvider owns one connection above the request routes, so moving
between the queue and a request does not reopen it. Settings is outside the
provider and opens no stream. Live updates are disabled unless the platform sets
the reshare.liveUpdates flag.

The connection is scoped to one side and the symbol resolved from the current
tenant. The side stays fixed for the app; an affiliation change reopens the
stream for the new tenant. Broker heartbeats keep an idle connection alive, and
the client reconnects with backoff when delivery stops. Errors that look
permanent are not retried indefinitely.

From broker message to cache invalidation

The current stream contains outgoing ISO 18626 message traffic, not a native
"patron request changed" event. The client reads the message header only to
identify relevant cached requests; it never treats the message body as a
replacement for a fresh broker response.

Either agency request id in the header may identify the local request. The
client first compares those ids with record query keys, which are available even
while a request is loading. Cached record data supplies the requester-id
fallback needed by lending messages that do not carry a supplying-agency id.

For each resolved request, the client cancels older in-flight detail requests
and marks the record, actions, event history and notifications out of date.
Cancellation prevents an older response from arriving later and making the
cache appear current again. Every frame also marks the request-list queries,
even when no cached detail request can be resolved.

Invalidation itself sends no request. Active queries refetch after short,
separate debounces for chat, request details and the broader request list. The
delays coalesce the bursts produced by a transition, while maximum waits prevent
continuous activity from postponing refresh forever. Inactive request queries
remain invalidated and refetch when they are observed again.

Request actions are disabled while their record or action data is awaiting a
refresh, as well as while an action submission is in flight. That state comes
from React Query rather than a second flag maintained by the event listener.

Disconnects and gaps

The broker supplies no event ids or replay. A disconnected client therefore
cannot recover the exact messages it may have missed. After an interruption,
the first successful delivery tells listeners to distrust all cached request
data. Active queries are reconciled and inactive ones stay marked for their next
observer.

This makes reconnects safe for the cache, but it does not make the stream
durable. Events can still be lost before the client knows a gap exists, during
initial connection setup, or when a slow connection is evicted by the broker.

What the current stream cannot report

The stream follows peer-directed message traffic. It is not a complete account
of patron-request changes. In particular, it does not reliably report:

  • newly arrived lending requests;
  • local edits or other changes that send no peer message;
  • work performed by another user or tab on the same side;
  • every automatic, scheduled or retry transition;
  • same-side chat activity.

The debounced list refresh is consequently useful but incomplete. Normal query
freshness, reopening a screen and manual refresh remain part of the consistency
model; staleTime alone does not initiate a fetch.

A complete live-update contract needs broker-native events emitted after a
patron-request change commits, addressed to the side and symbol that own the
request and carrying its local id. Replay or an explicit reset mechanism would
then make reconnects recoverable rather than merely conservative.

Code map

  • stripes-reshare/src/BrokerEvents.js owns the connection, parsing, watchdog,
    reconnect and gap notification.
  • stripes-reshare/src/RequestCacheSync.js translates events and gaps into
    cache policy.
  • stripes-reshare/src/requestQueries.js defines request query keys and message
    id matching.
  • stripes-reshare/src/useIsActionPending.js derives whether actions should be
    disabled.

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

Adds SSE-driven live updates for patron request detail views, including reconnect handling, query invalidation, and action settling.

Changes:

  • Adds a shared broker event-stream provider and request-event hook.
  • Refreshes request queries after matching peer events and disables stale actions while settling.
  • Adds integration/unit tests, mocks, exports, and environment flags.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
ui-rs/test/jest/setupFiles.js Adds text codec test polyfills.
ui-rs/src/test/stripesCore.js Supports per-test ReShare flags.
ui-rs/src/test/okapiKyMock.js Adds mock event streams.
ui-rs/src/routes/ViewRoute.test.js Tests event-driven refresh behavior.
ui-rs/src/routes/ViewRoute.js Subscribes the viewed request to events.
ui-rs/src/index.js Mounts the shared event provider.
stripes-reshare/src/useRequestEvents.test.js Tests matching, settling, and refreshes.
stripes-reshare/src/useRequestEvents.js Implements request event handling.
stripes-reshare/src/useIsActionPending.test.js Tests settling-state subscriptions.
stripes-reshare/src/useIsActionPending.js Includes event settling in pending state.
stripes-reshare/src/BrokerEvents.test.js Tests stream parsing and recovery.
stripes-reshare/src/BrokerEvents.js Implements SSE connection management.
stripes-reshare/index.js Exports the new APIs.
platform-rs-dev/stripes.config.js Enables development live updates.
environments/platform-resharex/stripes.config.js Adds environment feature flags.
environments/platform-resharex/consortial.stripes.config.js Adds consortial feature flags.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread environments/platform-resharex/stripes.config.js Outdated
Comment thread environments/platform-resharex/consortial.stripes.config.js Outdated
Comment thread stripes-reshare/src/useRequestEvents.js Outdated
Comment thread stripes-reshare/src/useIsActionPending.js Outdated
Comment thread ui-rs/src/routes/ViewRoute.js Outdated
Comment thread stripes-reshare/src/useRequestEvents.js Outdated

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 18 out of 18 changed files in this pull request and generated 3 comments.

Comment thread stripes-reshare/src/RequestCacheSync.js
Comment thread stripes-reshare/src/RequestCacheSync.js
Comment thread stripes-reshare/src/useIsActionPending.js
@skomorokh
skomorokh marked this pull request as ready for review September 1, 2026 01:46
@jakub-id

jakub-id commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

@skomorokh LGTM for the demo. Merge it and I will make a PR in the broker that changes the nature of events to a signal only patron-request-updated with a the only payload being section that narrows it down. It will also hang off a new NOTIFY channel thet collects any relevant table update, not merely the arriving message.

@skomorokh
skomorokh merged commit 43eb3ca into main Sep 1, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants