




















@@ -8,6 +8,20 @@ import {
88resolveTailnetDnsHint,
99} from "./server-discovery.js";
101011+const DEFAULT_DISCOVERY_ADVERTISE_TIMEOUT_MS = 5_000;
12+13+function resolveDiscoveryAdvertiseTimeoutMs(env: NodeJS.ProcessEnv): number {
14+const raw = env.OPENCLAW_GATEWAY_DISCOVERY_ADVERTISE_TIMEOUT_MS?.trim();
15+if (!raw) {
16+return DEFAULT_DISCOVERY_ADVERTISE_TIMEOUT_MS;
17+}
18+const parsed = Number.parseInt(raw, 10);
19+if (!Number.isFinite(parsed) || parsed <= 0) {
20+return DEFAULT_DISCOVERY_ADVERTISE_TIMEOUT_MS;
21+}
22+return parsed;
23+}
24+1125export async function startGatewayDiscovery(params: {
1226machineDisplayName: string;
1327port: number;
@@ -32,6 +46,7 @@ export async function startGatewayDiscovery(params: {
3246const mdnsMinimal = mdnsMode !== "full";
3347const tailscaleEnabled = params.tailscaleMode !== "off";
3448const needsTailnetDns = localDiscoveryEnabled || params.wideAreaDiscoveryEnabled;
49+const advertiseTimeoutMs = resolveDiscoveryAdvertiseTimeoutMs(process.env);
3550const tailnetDns = needsTailnetDns
3651 ? await resolveTailnetDnsHint({ enabled: tailscaleEnabled })
3752 : undefined;
@@ -42,9 +57,14 @@ export async function startGatewayDiscovery(params: {
42574358if (localDiscoveryEnabled) {
4459const stops: Array<() => void | Promise<void>> = [];
60+let attemptedLocalDiscovery = false;
61+let stoppedLocalDiscovery = false;
4562for (const entry of params.gatewayDiscoveryServices ?? []) {
63+attemptedLocalDiscovery = true;
4664try {
47-const started = await entry.service.advertise({
65+let timer: ReturnType<typeof setTimeout> | undefined;
66+let timedOut = false;
67+const context = {
4868machineDisplayName: params.machineDisplayName,
4969gatewayPort: params.port,
5070gatewayTlsEnabled: params.gatewayTls?.enabled ?? false,
@@ -54,7 +74,50 @@ export async function startGatewayDiscovery(params: {
5474 tailnetDns,
5575 cliPath,
5676minimal: mdnsMinimal,
77+};
78+const advertisePromise = Promise.resolve()
79+.then(() => entry.service.advertise(context))
80+.then(
81+async (started) => {
82+if (timedOut) {
83+if (started?.stop) {
84+if (stoppedLocalDiscovery) {
85+try {
86+await started.stop();
87+} catch (err) {
88+params.logDiscovery.warn(`gateway discovery stop failed: ${String(err)}`);
89+}
90+} else {
91+stops.push(started.stop);
92+}
93+}
94+params.logDiscovery.warn(
95+`gateway discovery service completed after startup timeout (${entry.service.id}, plugin=${entry.pluginId})`,
96+);
97+}
98+return started;
99+},
100+(err) => {
101+params.logDiscovery.warn(
102+`gateway discovery service failed${timedOut ? " after startup timeout" : ""} (${entry.service.id}, plugin=${entry.pluginId}): ${String(err)}`,
103+);
104+return undefined;
105+},
106+);
107+const timeoutPromise = new Promise<undefined>((resolve) => {
108+timer = setTimeout(() => {
109+timedOut = true;
110+params.logDiscovery.warn(
111+`gateway discovery service timed out after ${advertiseTimeoutMs}ms (${entry.service.id}, plugin=${entry.pluginId}); continuing startup`,
112+);
113+resolve(undefined);
114+}, advertiseTimeoutMs);
115+timer.unref?.();
57116});
117+const started = await Promise.race([advertisePromise, timeoutPromise]);
118+if (timer) {
119+clearTimeout(timer);
120+}
58121if (started?.stop) {
59122stops.push(started.stop);
60123}
@@ -64,8 +127,9 @@ export async function startGatewayDiscovery(params: {
64127);
65128}
66129}
67-if (stops.length > 0) {
130+if (attemptedLocalDiscovery) {
68131bonjourStop = async () => {
132+stoppedLocalDiscovery = true;
69133for (const stop of stops.toReversed()) {
70134try {
71135await stop();
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。