Files
clinera-site/pi-worker/src/scheduler/lock.ts
T
Azreen Jamal 19420cc01d feat: add pi-worker service - autonomous Asana task executor & project improvement agent
- Asana REST API client for task polling, section management, and commenting
- Pi CLI executor for running tasks with specialist agent teams
- Task loop: polls Asana To Do/Pi Worker sections, executes tasks, reports results
- Improvement loop: rotates through 8 improvement categories (code quality, security, docs, testing, etc)
- Health server on :8787
- File-based mutex locks with stale lock detection
- Docker + docker-compose deployment config
- deploy.sh for one-command deployment to cr-server-new via SSH/Incus
2026-03-06 15:26:13 +08:00

48 lines
1.1 KiB
TypeScript

import { writeFileSync, unlinkSync, readFileSync, existsSync } from "fs";
import { join } from "path";
export class FileLock {
private lockPath: string;
constructor(name: string, dir: string = "/tmp") {
this.lockPath = join(dir, `pi-worker-${name}.lock`);
}
acquire(): boolean {
// Check for stale lock first
if (existsSync(this.lockPath)) {
try {
const content = readFileSync(this.lockPath, "utf-8");
const lockTime = parseInt(content);
if (Date.now() - lockTime > 15 * 60 * 1000) {
// Stale lock, remove it
try { unlinkSync(this.lockPath); } catch {}
} else {
return false;
}
} catch {
// Corrupted lock file, remove it
try { unlinkSync(this.lockPath); } catch {}
}
}
// Atomic create
try {
writeFileSync(this.lockPath, Date.now().toString(), { flag: 'wx' });
return true;
} catch {
return false; // Another process got it first
}
}
release() {
try {
unlinkSync(this.lockPath);
} catch {}
}
isLocked(): boolean {
return existsSync(this.lockPath);
}
}