























@@ -9,6 +9,12 @@ import type {
99ChannelMessageUnknownSendReconciliationResult,
1010} from "../../channels/message/types.js";
1111import type { OpenClawConfig } from "../../config/types.openclaw.js";
12+import {
13+claimRecoveryEntry as claimSharedRecoveryEntry,
14+computeBackoffMs,
15+getErrnoCode,
16+releaseRecoveryEntry as releaseSharedRecoveryEntry,
17+} from "../delivery-recovery.shared.js";
1218import { formatErrorMessage } from "../errors.js";
1319import { resolveOutboundChannelMessageAdapter } from "./channel-resolution.js";
1420import type { OutboundDeliveryResult } from "./deliver-types.js";
@@ -26,6 +32,8 @@ import {
2632type QueuedDeliveryPayload,
2733} from "./delivery-queue-storage.js";
283435+export { computeBackoffMs };
36+2937export type RecoverySummary = {
3038recovered: number;
3139failed: number;
@@ -61,14 +69,6 @@ export type ActiveDeliveryClaimResult<T> =
61696270const MAX_RETRIES = 5;
637164-/** Backoff delays in milliseconds indexed by retry count (1-based). */
65-const BACKOFF_MS: readonly number[] = [
66-5_000, // retry 1: 5s
67-25_000, // retry 2: 25s
68-120_000, // retry 3: 2m
69-600_000, // retry 4: 10m
70-];
71-7272const PERMANENT_ERROR_PATTERNS: readonly RegExp[] = [
7373/no conversation reference found/i,
7474/chat not found/i,
@@ -97,12 +97,6 @@ function resolveRecoveryDeadlineMs(maxRecoveryMs: number | undefined): number {
9797return resolveExpiresAtMsFromDurationMs(durationMs) ?? resolveDateTimestampMs(Date.now());
9898}
9999100-function getErrnoCode(err: unknown): string | null {
101-return err && typeof err === "object" && "code" in err
102- ? String((err as { code?: unknown }).code)
103- : null;
104-}
105-106100function createEmptyRecoverySummary(): RecoverySummary {
107101return {
108102recovered: 0,
@@ -112,30 +106,18 @@ function createEmptyRecoverySummary(): RecoverySummary {
112106};
113107}
114108115-function claimRecoveryEntry(entryId: string): boolean {
116-if (entriesInProgress.has(entryId)) {
117-return false;
118-}
119-entriesInProgress.add(entryId);
120-return true;
121-}
122-123-function releaseRecoveryEntry(entryId: string): void {
124-entriesInProgress.delete(entryId);
125-}
126-127109export async function withActiveDeliveryClaim<T>(
128110entryId: string,
129111fn: () => Promise<T>,
130112): Promise<ActiveDeliveryClaimResult<T>> {
131-if (!claimRecoveryEntry(entryId)) {
113+if (!claimSharedRecoveryEntry(entriesInProgress, entryId)) {
132114return { status: "claimed-by-other-owner" };
133115}
134116135117try {
136118return { status: "claimed", value: await fn() };
137119} finally {
138-releaseRecoveryEntry(entryId);
120+releaseSharedRecoveryEntry(entriesInProgress, entryId);
139121}
140122}
141123@@ -326,14 +308,6 @@ async function moveEntryToFailedWithLogging(
326308}
327309}
328310329-/** Compute the backoff delay in ms for a given retry count. */
330-export function computeBackoffMs(retryCount: number): number {
331-if (retryCount <= 0) {
332-return 0;
333-}
334-return BACKOFF_MS[Math.min(retryCount - 1, BACKOFF_MS.length - 1)] ?? BACKOFF_MS.at(-1) ?? 0;
335-}
336-337311export function isEntryEligibleForRecoveryRetry(
338312entry: QueuedDelivery,
339313now: number,
@@ -513,7 +487,7 @@ export async function drainPendingDeliveries(opts: {
513487);
514488515489for (const entry of matchingEntries) {
516-if (!claimRecoveryEntry(entry.id)) {
490+if (!claimSharedRecoveryEntry(entriesInProgress, entry.id)) {
517491opts.log.info(`${opts.logLabel}: entry ${entry.id} is already being recovered`);
518492continue;
519493}
@@ -582,7 +556,7 @@ export async function drainPendingDeliveries(opts: {
582556);
583557}
584558} finally {
585-releaseRecoveryEntry(entry.id);
559+releaseSharedRecoveryEntry(entriesInProgress, entry.id);
586560}
587561}
588562} finally {
@@ -622,7 +596,7 @@ export async function recoverPendingDeliveries(opts: {
622596break;
623597}
624598625-if (!claimRecoveryEntry(entry.id)) {
599+if (!claimSharedRecoveryEntry(entriesInProgress, entry.id)) {
626600opts.log.info(`Recovery skipped for delivery ${entry.id}: already being processed`);
627601continue;
628602}
@@ -677,7 +651,7 @@ export async function recoverPendingDeliveries(opts: {
677651continue;
678652}
679653} finally {
680-releaseRecoveryEntry(entry.id);
654+releaseSharedRecoveryEntry(entriesInProgress, entry.id);
681655}
682656}
683657此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。