






















@@ -18,7 +18,10 @@ import {
1818import { clearTelegramRuntime, setTelegramRuntime } from "./runtime.js";
1919import type { TelegramProbeFn } from "./runtime.types.js";
2020import type { TelegramRuntime } from "./runtime.types.js";
21-import { resetTelegramStartupProbeLimiterForTests } from "./startup-probe-limiter.js";
21+import {
22+resetTelegramStartupProbeLimiterForTests,
23+withTelegramStartupProbeSlot,
24+} from "./startup-probe-limiter.js";
22252326const probeTelegram = vi.fn();
2427const monitorTelegramProvider = vi.fn();
@@ -157,6 +160,22 @@ async function waitForCondition(check: () => boolean, message: string, timeoutMs
157160throw new Error(message);
158161}
159162163+async function releaseStartupProbeControls(releaseProbe: Array<() => void>) {
164+for (let attempt = 0; attempt < 10; attempt += 1) {
165+const releases = releaseProbe.splice(0);
166+for (const release of releases) {
167+release();
168+}
169+await new Promise((resolve) => setTimeout(resolve, 0));
170+if (releaseProbe.length === 0) {
171+return;
172+}
173+}
174+for (const release of releaseProbe.splice(0)) {
175+release();
176+}
177+}
178+160179afterEach(async () => {
161180clearTelegramRuntime();
162181resetTelegramPollingLeasesForTests();
@@ -427,69 +446,91 @@ describe("telegramPlugin gateway startup", () => {
427446});
428447429448it("limits concurrent startup probes across Telegram accounts", async () => {
430-installTelegramRuntime();
431449const releaseProbe: Array<() => void> = [];
432450let activeProbes = 0;
433451let maxActiveProbes = 0;
434-probeTelegram.mockImplementation(async () => {
435-activeProbes += 1;
436-maxActiveProbes = Math.max(maxActiveProbes, activeProbes);
437-await new Promise<void>((resolve) => {
438-releaseProbe.push(resolve);
452+const runProbe = async () =>
453+await withTelegramStartupProbeSlot(undefined, async () => {
454+activeProbes += 1;
455+maxActiveProbes = Math.max(maxActiveProbes, activeProbes);
456+await new Promise<void>((resolve) => {
457+releaseProbe.push(resolve);
458+});
459+activeProbes -= 1;
439460});
440-activeProbes -= 1;
441-return {
442-ok: true,
443-status: null,
444-error: null,
445-elapsedMs: 12,
446-};
447-});
448-monitorTelegramProvider.mockResolvedValue(undefined);
449461450-const first = startTelegramAccount("alpha");
451-const second = startTelegramAccount("bravo");
452-const third = startTelegramAccount("charlie");
453-const tasks = [first.task, second.task, third.task];
462+const first = runProbe();
463+const second = runProbe();
464+const third = runProbe();
465+const tasks = [first, second, third];
454466try {
455467await waitForCondition(
456-() => probeTelegram.mock.calls.length === 2,
468+() => releaseProbe.length === 2,
457469"expected two startup probes to begin",
458470);
459471expect(maxActiveProbes).toBe(2);
460-expect(releaseProbe).toHaveLength(2);
461472462473releaseProbe.shift()?.();
463474await waitForCondition(
464-() => probeTelegram.mock.calls.length === 3,
475+() => releaseProbe.length === 2,
465476"expected queued startup probe to begin after a slot opens",
466477);
467478expect(maxActiveProbes).toBe(2);
468-469-for (const release of releaseProbe.splice(0)) {
470-release();
471-}
472-await Promise.all(tasks);
473479} finally {
474-for (const release of releaseProbe.splice(0)) {
475-release();
476-}
477-await Promise.allSettled(tasks);
480+await releaseStartupProbeControls(releaseProbe);
478481}
479-expect(monitorTelegramProvider).toHaveBeenCalledTimes(3);
482+await Promise.all(tasks);
480483});
481484482485it("abandons a queued startup probe when the account aborts", async () => {
483-installTelegramRuntime();
484486const releaseProbe: Array<() => void> = [];
485487let startedProbes = 0;
488+const runProbe = async (abortSignal?: AbortSignal) =>
489+await withTelegramStartupProbeSlot(abortSignal, async () => {
490+startedProbes += 1;
491+if (startedProbes <= 2) {
492+await new Promise<void>((resolve) => {
493+releaseProbe.push(resolve);
494+});
495+}
496+});
497+498+const first = runProbe();
499+const second = runProbe();
500+const abortQueued = new AbortController();
501+const queued = runProbe(abortQueued.signal).then(
502+() => undefined,
503+(error: unknown) => error,
504+);
505+try {
506+await waitForCondition(
507+() => releaseProbe.length === 2,
508+"expected startup probe slots to fill",
509+);
510+abortQueued.abort();
511+} finally {
512+abortQueued.abort();
513+await releaseStartupProbeControls(releaseProbe);
514+}
515+await Promise.all([first, second]);
516+await expect(queued).resolves.toMatchObject({
517+message: "telegram startup probe wait aborted",
518+});
519+expect(startedProbes).toBe(2);
520+});
521+522+it("starts each Telegram monitor after a successful startup probe", async () => {
523+installTelegramRuntime();
524+const releaseProbe: Array<() => void> = [];
525+let activeProbes = 0;
526+let maxActiveProbes = 0;
486527probeTelegram.mockImplementation(async () => {
487-startedProbes += 1;
488-if (startedProbes <= 2) {
489- await new Promise<void>((resolve) => {
490- releaseProbe.push(resolve);
491- });
492-}
528+activeProbes += 1;
529+maxActiveProbes = Math.max(maxActiveProbes, activeProbes);
530+await new Promise<void>((resolve) => {
531+releaseProbe.push(resolve);
532+});
533+activeProbes -= 1;
493534return {
494535ok: true,
495536status: null,
@@ -499,31 +540,15 @@ describe("telegramPlugin gateway startup", () => {
499540});
500541monitorTelegramProvider.mockResolvedValue(undefined);
501542502-const first = startTelegramAccount("alpha");
503-const second = startTelegramAccount("bravo");
504-const abortQueued = new AbortController();
505-const queued = startTelegramAccount("charlie", {}, abortQueued.signal);
506-const tasks = [first.task, second.task, queued.task];
543+const account = startTelegramAccount("alpha");
507544try {
508-await waitForCondition(
509-() => probeTelegram.mock.calls.length === 2,
510-"expected startup probe slots to fill",
511-);
512-abortQueued.abort();
513-514-for (const release of releaseProbe.splice(0)) {
515-release();
516-}
517-await Promise.all(tasks);
545+await waitForCondition(() => releaseProbe.length === 1, "expected startup probe to begin");
518546} finally {
519-abortQueued.abort();
520-for (const release of releaseProbe.splice(0)) {
521-release();
522-}
523-await Promise.allSettled(tasks);
547+await releaseStartupProbeControls(releaseProbe);
524548}
525-expect(probeTelegram).toHaveBeenCalledTimes(2);
526-expect(monitorTelegramProvider).toHaveBeenCalledTimes(2);
549+await account.task;
550+expect(maxActiveProbes).toBe(1);
551+expect(monitorTelegramProvider).toHaveBeenCalledTimes(1);
527552});
528553529554it("releases a stopped stale polling lease for the account token", async () => {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。