MCPcopy
hub / github.com/colbymchenry/codegraph / acquire

Method acquire

src/utils.ts:237–279  ·  view source on GitHub ↗

* Acquire the lock. Throws if the lock is held by another live process.

()

Source from the content-addressed store, hash-verified

235 * Acquire the lock. Throws if the lock is held by another live process.
236 */
237 acquire(): void {
238 // Check for existing lock
239 if (fs.existsSync(this.lockPath)) {
240 try {
241 const content = fs.readFileSync(this.lockPath, 'utf-8').trim();
242 const pid = parseInt(content, 10);
243 const stat = fs.statSync(this.lockPath);
244 const lockAge = Date.now() - stat.mtimeMs;
245
246 // Treat locks older than the timeout as stale, regardless of PID
247 if (lockAge < FileLock.STALE_TIMEOUT_MS && !isNaN(pid) && this.isProcessAlive(pid)) {
248 throw new Error(
249 `CodeGraph database is locked by another process (PID ${pid}). ` +
250 `If this is stale, run 'codegraph unlock' or delete ${this.lockPath}`
251 );
252 }
253
254 // Stale lock (dead process or timed out) - remove it
255 fs.unlinkSync(this.lockPath);
256 } catch (err) {
257 if (err instanceof Error && err.message.includes('locked by another')) {
258 throw err;
259 }
260 // Other errors reading lock file - try to remove it
261 try { fs.unlinkSync(this.lockPath); } catch { /* ignore */ }
262 }
263 }
264
265 // Write our PID to the lock file using exclusive create flag
266 try {
267 fs.writeFileSync(this.lockPath, String(process.pid), { flag: 'wx' });
268 this.held = true;
269 } catch (err: any) {
270 if (err.code === 'EEXIST') {
271 // Race condition: another process grabbed the lock between our check and write
272 throw new Error(
273 'CodeGraph database is locked by another process. ' +
274 `If this is stale, run 'codegraph unlock' or delete ${this.lockPath}`
275 );
276 }
277 throw err;
278 }
279 }
280
281 /**
282 * Release the lock

Callers 2

withLockMethod · 0.95
withLockAsyncMethod · 0.95

Calls 1

isProcessAliveMethod · 0.95

Tested by

no test coverage detected