authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-04-05 09:53:53-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-04-05 16:53:53+00:00
loge0874b651d5c5fa5c578be932aada627b95c3f52
tree794069696e25f8753ad79daf22cbf14c4275ac95
parent12347082ef1c4bce3d4a96e4072b7ada9a5a5b29
signature Signed by PGP key B5690EEEBB952194

Raise slow RPC ack warning threshold to 15s (#1760)


2 files changed, 18 insertions(+), 6 deletions(-)

apps/web/src/rpc/requestLatencyState.ts+9-3
...@@ -3,8 +3,9 @@ import { Atom } from "effect/unstable/reactivity";...@@ -3,8 +3,9 @@ import { Atom } from "effect/unstable/reactivity";
33
4import { appAtomRegistry } from "./atomRegistry";4import { appAtomRegistry } from "./atomRegistry";
55
6export const SLOW_RPC_ACK_THRESHOLD_MS = 2_500;6export const SLOW_RPC_ACK_THRESHOLD_MS = 15_000;
7export const MAX_TRACKED_RPC_ACK_REQUESTS = 256;7export const MAX_TRACKED_RPC_ACK_REQUESTS = 256;
8let slowRpcAckThresholdMs = SLOW_RPC_ACK_THRESHOLD_MS;
89
9export interface SlowRpcAckRequest {10export interface SlowRpcAckRequest {
10 readonly requestId: string;11 readonly requestId: string;
...@@ -56,12 +57,12 @@ export function trackRpcRequestSent(requestId: string, tag: string): void {...@@ -56,12 +57,12 @@ export function trackRpcRequestSent(requestId: string, tag: string): void {
56 startedAt: new Date(startedAtMs).toISOString(),57 startedAt: new Date(startedAtMs).toISOString(),
57 startedAtMs,58 startedAtMs,
58 tag,59 tag,
59 thresholdMs: SLOW_RPC_ACK_THRESHOLD_MS,60 thresholdMs: slowRpcAckThresholdMs,
60 };61 };
61 const timeoutId = setTimeout(() => {62 const timeoutId = setTimeout(() => {
62 pendingRpcAckRequests.delete(requestId);63 pendingRpcAckRequests.delete(requestId);
63 appendSlowRpcAckRequest(request);64 appendSlowRpcAckRequest(request);
64 }, SLOW_RPC_ACK_THRESHOLD_MS);65 }, slowRpcAckThresholdMs);
6566
66 pendingRpcAckRequests.set(requestId, {67 pendingRpcAckRequests.set(requestId, {
67 request,68 request,
...@@ -119,9 +120,14 @@ function evictOldestPendingRpcRequestIfNeeded(): void {...@@ -119,9 +120,14 @@ function evictOldestPendingRpcRequestIfNeeded(): void {
119}120}
120121
121export function resetRequestLatencyStateForTests(): void {122export function resetRequestLatencyStateForTests(): void {
123 slowRpcAckThresholdMs = SLOW_RPC_ACK_THRESHOLD_MS;
122 clearAllTrackedRpcRequests();124 clearAllTrackedRpcRequests();
123}125}
124126
127export function setSlowRpcAckThresholdMsForTests(thresholdMs: number): void {
128 slowRpcAckThresholdMs = thresholdMs;
129}
130
125export function useSlowRpcAckRequests(): ReadonlyArray<SlowRpcAckRequest> {131export function useSlowRpcAckRequests(): ReadonlyArray<SlowRpcAckRequest> {
126 return useAtomValue(slowRpcAckRequestsAtom);132 return useAtomValue(slowRpcAckRequestsAtom);
127}133}
apps/web/src/wsTransport.test.ts+9-3
...@@ -5,7 +5,11 @@ import {...@@ -5,7 +5,11 @@ import {
5 __resetClientTracingForTests,5 __resetClientTracingForTests,
6 configureClientTracing,6 configureClientTracing,
7} from "./observability/clientTracing";7} from "./observability/clientTracing";
8import { getSlowRpcAckRequests, resetRequestLatencyStateForTests } from "./rpc/requestLatencyState";8import {
9 getSlowRpcAckRequests,
10 resetRequestLatencyStateForTests,
11 setSlowRpcAckThresholdMsForTests,
12} from "./rpc/requestLatencyState";
9import {13import {
10 getWsConnectionStatus,14 getWsConnectionStatus,
11 getWsConnectionUiState,15 getWsConnectionUiState,
...@@ -292,6 +296,8 @@ describe("WsTransport", () => {...@@ -292,6 +296,8 @@ describe("WsTransport", () => {
292 });296 });
293297
294 it("marks unary requests as slow until the first server ack arrives", async () => {298 it("marks unary requests as slow until the first server ack arrives", async () => {
299 const slowAckThresholdMs = 25;
300 setSlowRpcAckThresholdMsForTests(slowAckThresholdMs);
295 const transport = new WsTransport("ws://localhost:3020");301 const transport = new WsTransport("ws://localhost:3020");
296302
297 const requestPromise = transport.request((client) =>303 const requestPromise = transport.request((client) =>
...@@ -320,7 +326,7 @@ describe("WsTransport", () => {...@@ -320,7 +326,7 @@ describe("WsTransport", () => {
320 tag: WS_METHODS.serverUpsertKeybinding,326 tag: WS_METHODS.serverUpsertKeybinding,
321 },327 },
322 ]);328 ]);
323 }, 5_000);329 }, 1_000);
324330
325 socket.serverMessage(331 socket.serverMessage(
326 JSON.stringify({332 JSON.stringify({
...@@ -343,7 +349,7 @@ describe("WsTransport", () => {...@@ -343,7 +349,7 @@ describe("WsTransport", () => {
343 expect(getSlowRpcAckRequests()).toEqual([]);349 expect(getSlowRpcAckRequests()).toEqual([]);
344350
345 await transport.dispose();351 await transport.dispose();
346 }, 10_000);352 }, 5_000);
347353
348 it("sends unary RPC requests and resolves successful exits", async () => {354 it("sends unary RPC requests and resolves successful exits", async () => {
349 const transport = new WsTransport("ws://localhost:3020");355 const transport = new WsTransport("ws://localhost:3020");