惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

F
Fortinet All Blogs
爱范儿
爱范儿
V
Visual Studio Blog
Engineering at Meta
Engineering at Meta
B
Blog
云风的 BLOG
云风的 BLOG
G
Google Developers Blog
MongoDB | Blog
MongoDB | Blog
博客园 - Franky
U
Unit 42
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
WordPress大学
WordPress大学
D
DataBreaches.Net
B
Blog RSS Feed
小众软件
小众软件
人人都是产品经理
人人都是产品经理
I
InfoQ
P
Proofpoint News Feed
博客园 - 聂微东
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
J
Java Code Geeks
The GitHub Blog
The GitHub Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报

Recent Commits to openclaw:main

test: merge chat side-result checks · openclaw/openclaw@ddd2c2a test: merge cron history checks · openclaw/openclaw@f7eb746 test: merge responsive navigation shell checks · openclaw/openclaw@c2e4b47 docs(changelog): add codex oauth fixes · openclaw/openclaw@628e6cd test: merge navigation routing cases · openclaw/openclaw@5d8cecb Tests: mock channel registry bundled fallback · openclaw/openclaw@2b08233 Secrets: avoid broad web search discovery for single plugin config · openclaw/openclaw@a464f59 test: merge config view browser checks · openclaw/openclaw@20cf511 fix(status): align oauth health with runtime · openclaw/openclaw@eed7116 feat: add macOS screen snapshots for monitor preview (#67954) thanks … · openclaw/openclaw@f377db1 fix: report shared auth scopes in hello-ok (#67810) thanks @BunsDev · openclaw/openclaw@0b6c39b Auto-reply: avoid eager bundled route fallback · openclaw/openclaw@3ea1bf4 Tests: narrow session binding contract setup · openclaw/openclaw@54e4e16 fix(macOS): enable undo/redo in webchat composer text input (#34962) · openclaw/openclaw@00951dc Tests: speed up channel setup promotion · openclaw/openclaw@82b529a Docs: refresh agent instructions · openclaw/openclaw@5775fe2 fix(auth): serialize OAuth refresh across agents to fix #26322 (#67876) · openclaw/openclaw@8e79080 test: allow ollama public surface boundary test · openclaw/openclaw@7d4f1a6 Docs: add test performance guardrails · openclaw/openclaw@89706d3 Tests: restore context-engine usage proof · openclaw/openclaw@e4c4f95 Tests: slim context engine runtime coverage · openclaw/openclaw@74c198f ci: retry failed custom checkouts · openclaw/openclaw@0ee5baf test: trim duplicate provider auth onboarding cases · openclaw/openclaw@1ffc02e matrix: fix sessions_spawn --thread subagent session spawning (#67643) · openclaw/openclaw@1ce2596 test: reduce auth choice fixture churn · openclaw/openclaw@857b9cd test: mock health status config boundaries · openclaw/openclaw@9d5ab4a test: mock onboard config io boundary · openclaw/openclaw@299694d test: mock legacy state plugin boundaries · openclaw/openclaw@2713089 test: mock channel install boundaries · openclaw/openclaw@b945248 test: mock doctor preview channel boundaries · openclaw/openclaw@b1a3ad4
Fail package update on unhealthy restart (#72422) · openc...
Takhoffman · 2026-04-27 · via Recent Commits to openclaw:main

@@ -26,6 +26,7 @@ const WINDOWS_STOPPED_FREE_EARLY_EXIT_GRACE_MS = 90_000;

2626

export type GatewayRestartWaitOutcome =

2727

| "healthy"

2828

| "plugin-errors"

29+

| "channel-errors"

2930

| "version-mismatch"

3031

| "stale-pids"

3132

| "stopped-free"

@@ -38,6 +39,7 @@ export type GatewayRestartSnapshot = {

3839

staleGatewayPids: number[];

3940

gatewayVersion?: string | null;

4041

activatedPluginErrors?: PluginHealthErrorSummary[];

42+

channelProbeErrors?: Array<{ id: string; error: string }>;

4143

expectedVersion?: string;

4244

versionMismatch?: {

4345

expected: string;

@@ -56,6 +58,7 @@ type GatewayReachability = {

5658

reachable: boolean;

5759

gatewayVersion: string | null;

5860

activatedPluginErrors: PluginHealthErrorSummary[];

61+

channelProbeErrors: Array<{ id: string; error: string }>;

5962

};

60636164

function hasListenerAttributionGap(portUsage: PortUsage): boolean {

@@ -154,13 +157,50 @@ function readActivatedPluginErrors(health: unknown): PluginHealthErrorSummary[]

154157

});

155158

}

156159160+

function readChannelProbeErrors(health: unknown): Array<{ id: string; error: string }> {

161+

if (!health || typeof health !== "object") {

162+

return [];

163+

}

164+

const channels = (health as { channels?: unknown }).channels;

165+

if (!channels || typeof channels !== "object" || Array.isArray(channels)) {

166+

return [];

167+

}

168+

const errors: Array<{ id: string; error: string }> = [];

169+

for (const [id, summary] of Object.entries(channels)) {

170+

if (!summary || typeof summary !== "object") {

171+

continue;

172+

}

173+

const probe = (summary as { probe?: unknown }).probe;

174+

if (!probe || typeof probe !== "object") {

175+

continue;

176+

}

177+

const ok = (probe as { ok?: unknown }).ok;

178+

if (ok !== false) {

179+

continue;

180+

}

181+

const error = (probe as { error?: unknown }).error;

182+

errors.push({

183+

id,

184+

error: typeof error === "string" && error.trim() ? error : "probe failed",

185+

});

186+

}

187+

return errors;

188+

}

189+157190

function applyActivatedPluginErrors(snapshot: GatewayRestartSnapshot): GatewayRestartSnapshot {

158191

if (!snapshot.activatedPluginErrors?.length) {

159192

return snapshot;

160193

}

161194

return { ...snapshot, healthy: false };

162195

}

163196197+

function applyChannelProbeErrors(snapshot: GatewayRestartSnapshot): GatewayRestartSnapshot {

198+

if (!snapshot.channelProbeErrors?.length) {

199+

return snapshot;

200+

}

201+

return { ...snapshot, healthy: false };

202+

}

203+164204

async function confirmGatewayReachable(params: {

165205

port: number;

166206

includeHealthDetails?: boolean;

@@ -177,6 +217,7 @@ async function confirmGatewayReachable(params: {

177217

reachable: probe.ok || looksLikeAuthClose(probe.close?.code, probe.close?.reason),

178218

gatewayVersion: probe.server?.version ?? null,

179219

activatedPluginErrors: readActivatedPluginErrors(probe.health),

220+

channelProbeErrors: readChannelProbeErrors(probe.health),

180221

};

181222

}

182223

@@ -217,13 +258,15 @@ export async function inspectGatewayRestart(params: {

217258

const expectedVersion = normalizeOptionalString(params.expectedVersion);

218259

let reachability: GatewayReachability | null = null;

219260

let activatedPluginErrors: PluginHealthErrorSummary[] = [];

261+

let channelProbeErrors: Array<{ id: string; error: string }> = [];

220262

const loadReachability = async () => {

221263

if (!reachability) {

222264

reachability = await confirmGatewayReachable({

223265

port: params.port,

224266

includeHealthDetails: Boolean(expectedVersion),

225267

});

226268

activatedPluginErrors = reachability.activatedPluginErrors;

269+

channelProbeErrors = reachability.channelProbeErrors;

227270

}

228271

return reachability;

229272

};

@@ -251,19 +294,24 @@ export async function inspectGatewayRestart(params: {

251294

try {

252295

const reachable = await loadReachability();

253296

if (reachable.reachable) {

254-

return applyActivatedPluginErrors(

255-

applyExpectedVersion(

256-

{

257-

runtime,

258-

portUsage,

259-

healthy: true,

260-

staleGatewayPids: [],

261-

gatewayVersion: reachable.gatewayVersion,

262-

...(reachable.activatedPluginErrors.length > 0

263-

? { activatedPluginErrors: reachable.activatedPluginErrors }

264-

: {}),

265-

},

266-

expectedVersion,

297+

return applyChannelProbeErrors(

298+

applyActivatedPluginErrors(

299+

applyExpectedVersion(

300+

{

301+

runtime,

302+

portUsage,

303+

healthy: true,

304+

staleGatewayPids: [],

305+

gatewayVersion: reachable.gatewayVersion,

306+

...(reachable.activatedPluginErrors.length > 0

307+

? { activatedPluginErrors: reachable.activatedPluginErrors }

308+

: {}),

309+

...(reachable.channelProbeErrors.length > 0

310+

? { channelProbeErrors: reachable.channelProbeErrors }

311+

: {}),

312+

},

313+

expectedVersion,

314+

),

267315

),

268316

);

269317

}

@@ -307,6 +355,9 @@ export async function inspectGatewayRestart(params: {

307355

if (reachable.activatedPluginErrors.length > 0) {

308356

healthy = false;

309357

}

358+

if (reachable.channelProbeErrors.length > 0) {

359+

healthy = false;

360+

}

310361

} catch {

311362

healthy = false;

312363

}

@@ -340,17 +391,20 @@ export async function inspectGatewayRestart(params: {

340391

]),

341392

);

342393343-

return applyActivatedPluginErrors(

344-

applyExpectedVersion(

345-

{

346-

runtime,

347-

portUsage,

348-

healthy,

349-

staleGatewayPids,

350-

...(gatewayVersion !== undefined ? { gatewayVersion } : {}),

351-

...(activatedPluginErrors.length ? { activatedPluginErrors } : {}),

352-

},

353-

expectedVersion,

394+

return applyChannelProbeErrors(

395+

applyActivatedPluginErrors(

396+

applyExpectedVersion(

397+

{

398+

runtime,

399+

portUsage,

400+

healthy,

401+

staleGatewayPids,

402+

...(gatewayVersion !== undefined ? { gatewayVersion } : {}),

403+

...(activatedPluginErrors.length ? { activatedPluginErrors } : {}),

404+

...(channelProbeErrors.length ? { channelProbeErrors } : {}),

405+

},

406+

expectedVersion,

407+

),

354408

),

355409

);

356410

}

@@ -415,6 +469,9 @@ export async function waitForGatewayHealthyRestart(params: {

415469

if (snapshot.activatedPluginErrors?.length) {

416470

return withWaitContext(snapshot, "plugin-errors", attempt * delayMs);

417471

}

472+

if (snapshot.channelProbeErrors?.length) {

473+

return withWaitContext(snapshot, "channel-errors", attempt * delayMs);

474+

}

418475

if (snapshot.versionMismatch) {

419476

return withWaitContext(snapshot, "version-mismatch", attempt * delayMs);

420477

}

@@ -493,6 +550,12 @@ export function renderRestartDiagnostics(snapshot: GatewayRestartSnapshot): stri

493550

lines.push(`- ${plugin.id}: ${plugin.error}`);

494551

}

495552

}

553+

if (snapshot.channelProbeErrors?.length) {

554+

lines.push("Channel health probe errors:");

555+

for (const channel of snapshot.channelProbeErrors) {

556+

lines.push(`- ${channel.id}: ${channel.error}`);

557+

}

558+

}

496559

const runtimeSummary = [

497560

snapshot.runtime.status ? `status=${snapshot.runtime.status}` : null,

498561

snapshot.runtime.state ? `state=${snapshot.runtime.state}` : null,