MCPcopy Create free account
hub / github.com/claude-code-best/claude-code / lockCurrentVersion

Function lockCurrentVersion

src/utils/nativeInstaller/installer.ts:1045–1153  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

1043 * (unlike mtime-based locking which requires a 30-day timeout)
1044 */
1045export async function lockCurrentVersion(): Promise<void> {
1046 const dirs = getBaseDirectories()
1047
1048 // Only lock if we're running from the versions directory
1049 if (!process.execPath.includes(dirs.versions)) {
1050 return
1051 }
1052
1053 const versionPath = resolve(process.execPath)
1054 try {
1055 const lockfilePath = getLockFilePathFromVersionPath(dirs, versionPath)
1056
1057 // Ensure locks directory exists
1058 await mkdir(dirs.locks, { recursive: true })
1059
1060 if (isPidBasedLockingEnabled()) {
1061 // Acquire PID-based lock and hold it for the process lifetime
1062 // PID-based locking allows immediate detection of crashed processes
1063 // while still surviving laptop sleep (process is suspended but PID exists)
1064 const acquired = await acquireProcessLifetimeLock(
1065 versionPath,
1066 lockfilePath,
1067 )
1068
1069 if (!acquired) {
1070 logEvent('tengu_version_lock_failed', {
1071 is_pid_based: true,
1072 is_lifetime_lock: true,
1073 })
1074 logLockAcquisitionError(
1075 versionPath,
1076 new Error('Lock already held by another process'),
1077 )
1078 return
1079 }
1080
1081 logEvent('tengu_version_lock_acquired', {
1082 is_pid_based: true,
1083 is_lifetime_lock: true,
1084 })
1085 logForDebugging(`Acquired PID lock on running version: ${versionPath}`)
1086 } else {
1087 // Acquire mtime-based lock and never release it (until process exits)
1088 // Use 30 days for stale to prevent the lock from being considered stale during
1089 // normal usage. This is critical because laptop sleep suspends the process,
1090 // stopping the mtime heartbeat. 30 days is long enough for any realistic session
1091 // while still allowing eventual cleanup of abandoned locks.
1092 let release: (() => Promise<void>) | undefined
1093 try {
1094 release = await lockfile.lock(versionPath, {
1095 stale: LOCK_STALE_MS,
1096 retries: 0, // Don't retry - if we can't lock, that's fine
1097 lockfilePath,
1098 // Handle lock compromise gracefully (e.g., if another process deletes the lock directory)
1099 onCompromised: (err: Error) => {
1100 logForDebugging(
1101 `NON-FATAL: Lock on running version was compromised: ${err.message}`,
1102 { level: 'info' },

Callers 1

setupFunction · 0.85

Calls 13

getBaseDirectoriesFunction · 0.85
mkdirFunction · 0.85
isPidBasedLockingEnabledFunction · 0.85
logEventFunction · 0.85
logLockAcquisitionErrorFunction · 0.85
registerCleanupFunction · 0.85
isENOENTFunction · 0.85
resolveFunction · 0.50
logForDebuggingFunction · 0.50
releaseFunction · 0.50

Tested by

no test coverage detected