@@ -7,11 +7,11 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
77import { homedir } from "node:os" ;
88import { dirname , join } from "node:path" ;
99import { resolveIntegerOption } from "@openclaw/normalization-core/number-coercion" ;
10- import lockfile from "proper-lockfile" ;
1110import { mergeDeep } from "../../infra/deep-merge.js" ;
1211import type { Transport } from "../../llm/types.js" ;
1312import { CONFIG_DIR_NAME , getAgentDir } from "../config.js" ;
1413import { DEFAULT_HTTP_IDLE_TIMEOUT_MS , parseHttpIdleTimeoutMs } from "./http-dispatcher.js" ;
14+ import { acquireLockSyncWithRetry } from "./storage-lock.js" ;
1515
1616interface CompactionSettings {
1717 enabled ?: boolean ; // default: true
@@ -147,33 +147,6 @@ export class FileSettingsStorage implements SettingsStorage {
147147 this . projectSettingsPath = join ( cwd , CONFIG_DIR_NAME , "settings.json" ) ;
148148 }
149149
150- private acquireLockSyncWithRetry ( path : string ) : ( ) => void {
151- const maxAttempts = 10 ;
152- const delayMs = 20 ;
153- let lastError : unknown ;
154-
155- for ( let attempt = 1 ; attempt <= maxAttempts ; attempt ++ ) {
156- try {
157- return lockfile . lockSync ( path , { realpath : false } ) ;
158- } catch ( error ) {
159- const code =
160- typeof error === "object" && error !== null && "code" in error
161- ? String ( ( error as { code ?: unknown } ) . code )
162- : undefined ;
163- if ( code !== "ELOCKED" || attempt === maxAttempts ) {
164- throw error ;
165- }
166- lastError = error ;
167- const start = Date . now ( ) ;
168- while ( Date . now ( ) - start < delayMs ) {
169- // Sleep synchronously to avoid changing callers to async.
170- }
171- }
172- }
173-
174- throw ( lastError as Error ) ?? new Error ( "Failed to acquire settings lock" ) ;
175- }
176-
177150 withLock ( scope : SettingsScope , fn : ( current : string | undefined ) => string | undefined ) : void {
178151 const path = scope === "global" ? this . globalSettingsPath : this . projectSettingsPath ;
179152 const dir = dirname ( path ) ;
@@ -183,7 +156,7 @@ export class FileSettingsStorage implements SettingsStorage {
183156 // Only create directory and lock if file exists or we need to write
184157 const fileExists = existsSync ( path ) ;
185158 if ( fileExists ) {
186- release = this . acquireLockSyncWithRetry ( path ) ;
159+ release = acquireLockSyncWithRetry ( path ) ;
187160 }
188161 const current = fileExists ? readFileSync ( path , "utf-8" ) : undefined ;
189162 const next = fn ( current ) ;
@@ -193,7 +166,7 @@ export class FileSettingsStorage implements SettingsStorage {
193166 mkdirSync ( dir , { recursive : true } ) ;
194167 }
195168 if ( ! release ) {
196- release = this . acquireLockSyncWithRetry ( path ) ;
169+ release = acquireLockSyncWithRetry ( path ) ;
197170 }
198171 writeFileSync ( path , next , "utf-8" ) ;
199172 }
0 commit comments