docs(frontend): document SSE reconnect cursor + backoff reset rationale
This commit is contained in:
@@ -339,6 +339,12 @@ export default function BoardGroupDetailPage() {
|
|||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the newest `created_at` timestamp in a list of memory items.
|
||||||
|
*
|
||||||
|
* We pass this as `since` when reconnecting SSE so we don't re-stream the
|
||||||
|
* entire chat history after transient disconnects.
|
||||||
|
*/
|
||||||
const latestMemoryTimestamp = useCallback((items: BoardGroupMemoryRead[]) => {
|
const latestMemoryTimestamp = useCallback((items: BoardGroupMemoryRead[]) => {
|
||||||
if (!items.length) return undefined;
|
if (!items.length) return undefined;
|
||||||
const latest = items.reduce((max, item) => {
|
const latest = items.reduce((max, item) => {
|
||||||
@@ -405,11 +411,13 @@ export default function BoardGroupDetailPage() {
|
|||||||
while (!isCancelled) {
|
while (!isCancelled) {
|
||||||
const { value, done } = await reader.read();
|
const { value, done } = await reader.read();
|
||||||
if (done) break;
|
if (done) break;
|
||||||
|
|
||||||
|
// Consider the stream healthy once we receive any bytes (including pings)
|
||||||
|
// and reset the backoff so a later disconnect doesn't wait the full max.
|
||||||
if (value && value.length) {
|
if (value && value.length) {
|
||||||
// Consider the stream healthy once we receive any bytes (including pings),
|
|
||||||
// then reset the backoff for future reconnects.
|
|
||||||
backoff.reset();
|
backoff.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer += decoder.decode(value, { stream: true });
|
buffer += decoder.decode(value, { stream: true });
|
||||||
buffer = buffer.replace(/\r\n/g, "\n");
|
buffer = buffer.replace(/\r\n/g, "\n");
|
||||||
let boundary = buffer.indexOf("\n\n");
|
let boundary = buffer.indexOf("\n\n");
|
||||||
|
|||||||
@@ -1315,6 +1315,12 @@ export default function BoardDetailPage() {
|
|||||||
return () => window.clearTimeout(timeout);
|
return () => window.clearTimeout(timeout);
|
||||||
}, [chatMessages, isChatOpen]);
|
}, [chatMessages, isChatOpen]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an ISO timestamp for the newest board chat message.
|
||||||
|
*
|
||||||
|
* Used as the `since` cursor when (re)connecting to the SSE endpoint so we
|
||||||
|
* don't re-stream the entire chat log.
|
||||||
|
*/
|
||||||
const latestChatTimestamp = (items: BoardChatMessage[]) => {
|
const latestChatTimestamp = (items: BoardChatMessage[]) => {
|
||||||
if (!items.length) return undefined;
|
if (!items.length) return undefined;
|
||||||
const latest = items.reduce((max, item) => {
|
const latest = items.reduce((max, item) => {
|
||||||
@@ -1373,9 +1379,9 @@ export default function BoardDetailPage() {
|
|||||||
while (!isCancelled) {
|
while (!isCancelled) {
|
||||||
const { value, done } = await reader.read();
|
const { value, done } = await reader.read();
|
||||||
if (done) break;
|
if (done) break;
|
||||||
|
// Consider the stream healthy once we receive any bytes (including pings)
|
||||||
|
// and reset the backoff so a later disconnect doesn't wait the full max.
|
||||||
if (value && value.length) {
|
if (value && value.length) {
|
||||||
// Consider the stream "healthy" once we receive any bytes (including pings),
|
|
||||||
// then reset the backoff for future reconnects.
|
|
||||||
backoff.reset();
|
backoff.reset();
|
||||||
}
|
}
|
||||||
buffer += decoder.decode(value, { stream: true });
|
buffer += decoder.decode(value, { stream: true });
|
||||||
|
|||||||
Reference in New Issue
Block a user