fix(feishu): clamp sequential queue timeouts · openclaw/openclaw@fab8d29
steipete
·
2026-05-31
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
|
| 1 | +import { MAX_TIMER_TIMEOUT_MS } from "openclaw/plugin-sdk/number-runtime"; |
1 | 2 | import { afterEach, describe, expect, it, vi } from "vitest"; |
2 | 3 | import { createSequentialQueue } from "./sequential-queue.js"; |
3 | 4 | |
@@ -132,6 +133,25 @@ describe("createSequentialQueue", () => {
|
132 | 133 | await stuck; |
133 | 134 | }); |
134 | 135 | |
| 136 | +it("clamps oversized task timeouts before scheduling", async () => { |
| 137 | +vi.useFakeTimers(); |
| 138 | +const setTimeoutSpy = vi.spyOn(globalThis, "setTimeout"); |
| 139 | +const enqueue = createSequentialQueue({ |
| 140 | +taskTimeoutMs: Number.MAX_SAFE_INTEGER, |
| 141 | +}); |
| 142 | +const gate = createDeferred(); |
| 143 | + |
| 144 | +const first = enqueue("feishu:default:chat-large-timeout", async () => { |
| 145 | +await gate.promise; |
| 146 | +}); |
| 147 | + |
| 148 | +await Promise.resolve(); |
| 149 | +expect(setTimeoutSpy).toHaveBeenCalledWith(expect.any(Function), MAX_TIMER_TIMEOUT_MS); |
| 150 | + |
| 151 | +gate.resolve(); |
| 152 | +await first; |
| 153 | +}); |
| 154 | + |
135 | 155 | it("disables the timeout cap when taskTimeoutMs is 0 (legacy behavior)", async () => { |
136 | 156 | vi.useFakeTimers(); |
137 | 157 | const timeouts: Array<{ key: string; timeoutMs: number }> = []; |
|
| Original file line number | Diff line number | Diff line change |
|---|
|
| 1 | +import { resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime"; |
| 2 | + |
1 | 3 | /** |
2 | 4 | * Per-key serial task queue for Feishu inbound message handling. |
3 | 5 | * |
@@ -65,16 +67,17 @@ async function boundedRun(
|
65 | 67 | if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) { |
66 | 68 | return task(); |
67 | 69 | } |
| 70 | +const resolvedTimeoutMs = resolveTimerTimeoutMs(timeoutMs, DEFAULT_TASK_TIMEOUT_MS); |
68 | 71 | let timeoutHandle: ReturnType<typeof setTimeout> | undefined; |
69 | 72 | const timeoutPromise = new Promise<void>((resolve) => { |
70 | 73 | timeoutHandle = setTimeout(() => { |
71 | 74 | try { |
72 | | -onTaskTimeout?.(key, timeoutMs); |
| 75 | +onTaskTimeout?.(key, resolvedTimeoutMs); |
73 | 76 | } catch { |
74 | 77 | // Swallow logging errors so they cannot poison the queue chain. |
75 | 78 | } |
76 | 79 | resolve(); |
77 | | -}, timeoutMs); |
| 80 | +}, resolvedTimeoutMs); |
78 | 81 | }); |
79 | 82 | try { |
80 | 83 | await Promise.race([task(), timeoutPromise]); |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。