mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-24 11:25:50 -06:00
fix(macos): stop idle node setup CPU loop (#124599)
Make validated CLI cache writes idempotent and reuse the startup-scoped node worker launch across route retries, keeping the signed menu-bar app near-zero CPU while idle.\n\nCloses #124592
This commit is contained in:
committed by
GitHub
parent
147fa7e4c3
commit
c82dfdb43a
@@ -201,7 +201,7 @@ enum CLIInstaller {
|
||||
expectedVersion: GatewayEnvironment.expectedGatewayVersionString(),
|
||||
preferredPaths: preferredPaths)
|
||||
if status.isReady {
|
||||
self.rememberValidated(status)
|
||||
self.rememberValidated(status, defaults: AppDefaults.standard)
|
||||
return status
|
||||
}
|
||||
fallbackStatus = fallbackStatus ?? status
|
||||
@@ -225,7 +225,7 @@ enum CLIInstaller {
|
||||
expectedVersion: expectedVersion,
|
||||
preferredPaths: preferredPaths)
|
||||
if status.isReady {
|
||||
self.rememberValidated(status)
|
||||
self.rememberValidated(status, defaults: AppDefaults.standard)
|
||||
}
|
||||
return status
|
||||
}
|
||||
@@ -316,10 +316,14 @@ enum CLIInstaller {
|
||||
return environment
|
||||
}
|
||||
|
||||
private static func rememberValidated(_ status: Status) {
|
||||
static func rememberValidated(_ status: Status, defaults: UserDefaults) {
|
||||
guard case let .ready(location, version) = status else { return }
|
||||
AppDefaults.standard.set(location, forKey: cliValidatedExecutableKey)
|
||||
AppDefaults.standard.set(version, forKey: cliValidatedVersionKey)
|
||||
if defaults.string(forKey: cliValidatedExecutableKey) != location {
|
||||
defaults.set(location, forKey: cliValidatedExecutableKey)
|
||||
}
|
||||
if defaults.string(forKey: cliValidatedVersionKey) != version {
|
||||
defaults.set(version, forKey: cliValidatedVersionKey)
|
||||
}
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
|
||||
@@ -936,6 +936,12 @@ extension MacNodeModeCoordinator {
|
||||
guard self.nodeHostWorkerRetryTask == nil else {
|
||||
throw MacNodeHostWorkerRetryPolicy.RetryBackoffPending()
|
||||
}
|
||||
if let activeInput = self.activeNodeHostWorkerInput {
|
||||
// Worker launch metadata is startup-scoped. Route retries reuse it instead of
|
||||
// repeating CLI and runtime discovery until an explicit restart resets state.
|
||||
try self.nodeHostWorkerRetryPolicy.prepareForStart(activeInput)
|
||||
return try await nodeHostWorker.start(launch: activeInput.launch)
|
||||
}
|
||||
let launch: MacNodeHostWorkerLaunch
|
||||
do {
|
||||
if let projectLaunch = try await CommandResolver.projectNodeHostWorkerLaunch() {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import Foundation
|
||||
import os
|
||||
import Testing
|
||||
@testable import OpenClaw
|
||||
|
||||
@@ -291,6 +292,46 @@ struct CLIInstallerTests {
|
||||
defaults: defaults) == "2026.7.2")
|
||||
}
|
||||
|
||||
@Test func `validated CLI cache changes only when the ready tuple changes`() throws {
|
||||
let suite = "CLIInstallerTests.validated-cache.\(UUID().uuidString)"
|
||||
let defaults = try #require(UserDefaults(suiteName: suite))
|
||||
defer { defaults.removePersistentDomain(forName: suite) }
|
||||
let notificationCount = OSAllocatedUnfairLock(initialState: 0)
|
||||
let initialLocation = "/Users/test/.local/bin/openclaw"
|
||||
defaults.set(initialLocation, forKey: cliValidatedExecutableKey)
|
||||
defaults.set("2026.8.1", forKey: cliValidatedVersionKey)
|
||||
let observer = NotificationCenter.default.addObserver(
|
||||
forName: UserDefaults.didChangeNotification,
|
||||
object: defaults,
|
||||
queue: nil)
|
||||
{ _ in
|
||||
notificationCount.withLock { $0 += 1 }
|
||||
}
|
||||
defer { NotificationCenter.default.removeObserver(observer) }
|
||||
|
||||
CLIInstaller.rememberValidated(
|
||||
.ready(location: initialLocation, version: "2026.8.1"),
|
||||
defaults: defaults)
|
||||
|
||||
#expect(notificationCount.withLock { $0 } == 0)
|
||||
|
||||
let updatedLocation = "/opt/homebrew/bin/openclaw"
|
||||
CLIInstaller.rememberValidated(
|
||||
.ready(location: updatedLocation, version: "2026.8.1"),
|
||||
defaults: defaults)
|
||||
|
||||
#expect(notificationCount.withLock { $0 } == 1)
|
||||
#expect(defaults.string(forKey: cliValidatedExecutableKey) == updatedLocation)
|
||||
#expect(defaults.string(forKey: cliValidatedVersionKey) == "2026.8.1")
|
||||
|
||||
CLIInstaller.rememberValidated(
|
||||
.ready(location: updatedLocation, version: "2026.8.2"),
|
||||
defaults: defaults)
|
||||
|
||||
#expect(notificationCount.withLock { $0 } == 2)
|
||||
#expect(defaults.string(forKey: cliValidatedVersionKey) == "2026.8.2")
|
||||
}
|
||||
|
||||
@Test func `managed setup requires a parseable compatible version`() {
|
||||
let location = "/Users/test/.openclaw/bin/openclaw"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user