/ src / bridge / pollConfigDefaults.ts
pollConfigDefaults.ts
 1  /**
 2   * Bridge poll interval defaults. Extracted from pollConfig.ts so callers
 3   * that don't need live GrowthBook tuning (daemon via Agent SDK) can avoid
 4   * the growthbook.ts → config.ts → file.ts → sessionStorage.ts → commands.ts
 5   * transitive dependency chain.
 6   */
 7  
 8  /**
 9   * Poll interval when actively seeking work (no transport / below maxSessions).
10   * Governs user-visible "connecting…" latency on initial work pickup and
11   * recovery speed after the server re-dispatches a work item.
12   */
13  const POLL_INTERVAL_MS_NOT_AT_CAPACITY = 2000
14  
15  /**
16   * Poll interval when the transport is connected. Runs independently of
17   * heartbeat — when both are enabled, the heartbeat loop breaks out to poll
18   * at this interval. Set to 0 to disable at-capacity polling entirely.
19   *
20   * Server-side constraints that bound this value:
21   * - BRIDGE_LAST_POLL_TTL = 4h (Redis key expiry → environment auto-archived)
22   * - max_poll_stale_seconds = 24h (session-creation health gate, currently disabled)
23   *
24   * 10 minutes gives 24× headroom on the Redis TTL while still picking up
25   * server-initiated token-rotation redispatches within one poll cycle.
26   * The transport auto-reconnects internally for 10 minutes on transient WS
27   * failures, so poll is not the recovery path — it's strictly a liveness
28   * signal plus a backstop for permanent close.
29   */
30  const POLL_INTERVAL_MS_AT_CAPACITY = 600_000
31  
32  /**
33   * Multisession bridge (bridgeMain.ts) poll intervals. Defaults match the
34   * single-session values so existing GrowthBook configs without these fields
35   * preserve current behavior. Ops can tune these independently via the
36   * tengu_bridge_poll_interval_config GB flag.
37   */
38  const MULTISESSION_POLL_INTERVAL_MS_NOT_AT_CAPACITY =
39    POLL_INTERVAL_MS_NOT_AT_CAPACITY
40  const MULTISESSION_POLL_INTERVAL_MS_PARTIAL_CAPACITY =
41    POLL_INTERVAL_MS_NOT_AT_CAPACITY
42  const MULTISESSION_POLL_INTERVAL_MS_AT_CAPACITY = POLL_INTERVAL_MS_AT_CAPACITY
43  
44  export type PollIntervalConfig = {
45    poll_interval_ms_not_at_capacity: number
46    poll_interval_ms_at_capacity: number
47    non_exclusive_heartbeat_interval_ms: number
48    multisession_poll_interval_ms_not_at_capacity: number
49    multisession_poll_interval_ms_partial_capacity: number
50    multisession_poll_interval_ms_at_capacity: number
51    reclaim_older_than_ms: number
52    session_keepalive_interval_v2_ms: number
53  }
54  
55  export const DEFAULT_POLL_CONFIG: PollIntervalConfig = {
56    poll_interval_ms_not_at_capacity: POLL_INTERVAL_MS_NOT_AT_CAPACITY,
57    poll_interval_ms_at_capacity: POLL_INTERVAL_MS_AT_CAPACITY,
58    // 0 = disabled. When > 0, at-capacity loops send per-work-item heartbeats
59    // at this interval. Independent of poll_interval_ms_at_capacity — both may
60    // run (heartbeat periodically yields to poll). 60s gives 5× headroom under
61    // the server's 300s heartbeat TTL. Named non_exclusive to distinguish from
62    // the old heartbeat_interval_ms field (either-or semantics in pre-#22145
63    // clients — heartbeat suppressed poll). Old clients ignore this key; ops
64    // can set both fields during rollout.
65    non_exclusive_heartbeat_interval_ms: 0,
66    multisession_poll_interval_ms_not_at_capacity:
67      MULTISESSION_POLL_INTERVAL_MS_NOT_AT_CAPACITY,
68    multisession_poll_interval_ms_partial_capacity:
69      MULTISESSION_POLL_INTERVAL_MS_PARTIAL_CAPACITY,
70    multisession_poll_interval_ms_at_capacity:
71      MULTISESSION_POLL_INTERVAL_MS_AT_CAPACITY,
72    // Poll query param: reclaim unacknowledged work items older than this.
73    // Matches the server's DEFAULT_RECLAIM_OLDER_THAN_MS (work_service.py:24).
74    // Enables picking up stale-pending work after JWT expiry, when the prior
75    // ack failed because the session_ingress_token was already stale.
76    reclaim_older_than_ms: 5000,
77    // 0 = disabled. When > 0, push a silent {type:'keep_alive'} frame to
78    // session-ingress at this interval so upstream proxies don't GC an idle
79    // remote-control session. 2 min is the default. _v2: bridge-only gate
80    // (pre-v2 clients read the old key, new clients ignore it).
81    session_keepalive_interval_v2_ms: 120_000,
82  }