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. */
2export const THREAD_RESUME_MAX_REPLAY_EVENTS = 128;
3
4/** Maximum encoded event JSON allowed during a thread resume. */
5export const THREAD_RESUME_MAX_REPLAY_ENCODED_BYTES = 1_048_576;
6
7/** Encoded payload cost after events have been projected for the wire. */
8export 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
17export 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 */
33export 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