History

feat(orchestration): bound thread history and resume payloads

- Add paginated thread history with bounded snapshots and replay limits - Trim oversized wire payloads and support progressive mobile history loading

Julius Marminge committed 3 months ago

Commit 7d42d311 parent e3883a943 files · +4239 −211Browse files

Showing the changes to apps/server/src/orchestration-v2/ThreadStream.ts (1 of 43 files). Show all

Unified · Split

apps/server/src/orchestration-v2/ThreadStream.ts+51−0
@@ -0,0 +1,51 @@
1+/** Maximum number of reducer applications allowed during a thread resume. */
2+export const THREAD_RESUME_MAX_REPLAY_EVENTS = 128;
3+
4+/** Maximum encoded event JSON allowed during a thread resume. */
5+export const THREAD_RESUME_MAX_REPLAY_ENCODED_BYTES = 1_048_576;
6+
7+/** Encoded payload cost after events have been projected for the wire. */
8+export function threadReplayEncodedBytes(items: ReadonlyArray<unknown>): number {
9+ let total = 0;
10+ for (const item of items) {
11+ const encoded = JSON.stringify(item);
12+ total += Buffer.byteLength(encoded ?? "", "utf8");
13+ }
14+ return total;
15+}
16+
17+export type ThreadResumePlan =
18+ | {
19+ readonly mode: "replay";
20+ readonly afterSequence: number;
21+ readonly throughSequence: number;
22+ }
23+ | { readonly mode: "snapshot" };
24+
25+/**
26+ * Decide whether a thread subscription should replay the event gap after the
27+ * client's cursor or send a fresh snapshot instead.
28+ *
29+ * A client cursor above the high water mark is stale or invalid. Event count
30+ * limits reducer churn while encoded bytes limit a small number of large
31+ * updates. Either excess is cheaper to replace with one current snapshot.
32+ */
33+export function decideThreadResume(input: {
34+ readonly afterSequence: number;
35+ readonly highWater: number;
36+ readonly replayEventCount: number;
37+ readonly replayEncodedBytes: number;
38+}): ThreadResumePlan {
39+ if (
40+ input.afterSequence > input.highWater ||
41+ input.replayEventCount > THREAD_RESUME_MAX_REPLAY_EVENTS ||
42+ input.replayEncodedBytes > THREAD_RESUME_MAX_REPLAY_ENCODED_BYTES
43+ ) {
44+ return { mode: "snapshot" };
45+ }
46+ return {
47+ mode: "replay",
48+ afterSequence: input.afterSequence,
49+ throughSequence: input.highWater,
50+ };
51+}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t