Files
claw-apply/lib/lock.mjs
Matthew Jackson 8212f97aba refactor: normalize apply statuses, remove dead code, fix signal handler
- lib/apply/index.mjs: add STATUS_MAP to normalize platform-specific statuses
  to generic ones (no_button/no_submit/no_modal → skipped_no_apply).
  Documented all generic statuses for AI/developer reference.
- job_applier.mjs: handleResult now handles skipped_no_apply, default case
  logs + saves instead of silently dropping
- lib/linkedin.mjs: remove dead applyLinkedIn() and detectAts(), clean imports
  (~110 lines removed). Search-only module now.
- lib/wellfound.mjs: remove dead applyWellfound(), clean imports.
  Search-only module now.
- lib/lock.mjs: fix async signal handler — shutdown handlers now actually
  complete before process.exit()
- test_linkedin_login.mjs: add try/catch/finally with proper browser cleanup
- README: update status table with all current statuses

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 17:39:48 -08:00

50 lines
1.5 KiB
JavaScript

/**
* lock.mjs — Simple PID-based lockfile to prevent parallel runs
*/
import { existsSync, readFileSync, writeFileSync, unlinkSync } from 'fs';
import { resolve } from 'path';
export function acquireLock(name, dataDir) {
const lockFile = resolve(dataDir, `${name}.lock`);
if (existsSync(lockFile)) {
const pid = parseInt(readFileSync(lockFile, 'utf8').trim(), 10);
// Check if that process is still alive
try {
process.kill(pid, 0); // signal 0 = check existence only
console.error(`⚠️ ${name} already running (PID ${pid}). Exiting.`);
process.exit(0);
} catch {
// Stale lock — process is gone, safe to continue
console.warn(`🔓 Stale lock found (PID ${pid}), clearing.`);
}
}
writeFileSync(lockFile, String(process.pid));
// Release lock on exit (normal or crash)
const release = () => {
try { unlinkSync(lockFile); } catch {}
};
// Graceful shutdown — call registered cleanup before exiting
const shutdownHandlers = [];
const shutdown = (code) => {
console.log(`\n⚠️ ${name}: signal received, shutting down gracefully...`);
// Run handlers sequentially, then exit
(async () => {
for (const fn of shutdownHandlers) {
try { await fn(); } catch {}
}
release();
process.exit(code);
})();
};
process.on('exit', release);
process.on('SIGINT', () => shutdown(130));
process.on('SIGTERM', () => shutdown(143));
return { release, onShutdown: (fn) => shutdownHandlers.push(fn) };
}