* Acquire the lockfile with the given baseUrl and token. * Writes atomically with 0600 permissions (owner read/write only).
(
baseUrl: string,
token: string,
extra?: {
bindHost?: string;
port?: number;
networkBaseUrls?: string[];
}
)
| 36 | * Writes atomically with 0600 permissions (owner read/write only). |
| 37 | */ |
| 38 | async acquire( |
| 39 | baseUrl: string, |
| 40 | token: string, |
| 41 | extra?: { |
| 42 | bindHost?: string; |
| 43 | port?: number; |
| 44 | networkBaseUrls?: string[]; |
| 45 | } |
| 46 | ): Promise<void> { |
| 47 | const bindHost = extra?.bindHost?.trim() ? extra.bindHost.trim() : undefined; |
| 48 | const port = |
| 49 | typeof extra?.port === "number" && |
| 50 | Number.isInteger(extra.port) && |
| 51 | extra.port >= 0 && |
| 52 | extra.port <= 65535 |
| 53 | ? extra.port |
| 54 | : undefined; |
| 55 | |
| 56 | const data: ServerLockData = { |
| 57 | pid: process.pid, |
| 58 | baseUrl, |
| 59 | token, |
| 60 | startedAt: new Date().toISOString(), |
| 61 | bindHost, |
| 62 | port, |
| 63 | networkBaseUrls: extra?.networkBaseUrls?.length ? extra.networkBaseUrls : undefined, |
| 64 | }; |
| 65 | |
| 66 | // Ensure directory exists |
| 67 | const dir = path.dirname(this.lockPath); |
| 68 | try { |
| 69 | await fs.access(dir); |
| 70 | } catch { |
| 71 | await fs.mkdir(dir, { recursive: true }); |
| 72 | } |
| 73 | |
| 74 | // Write atomically by writing to temp file then renaming |
| 75 | const tempPath = `${this.lockPath}.${process.pid}.tmp`; |
| 76 | await fs.writeFile(tempPath, JSON.stringify(data, null, 2), { |
| 77 | mode: 0o600, // Owner read/write only |
| 78 | }); |
| 79 | await fs.rename(tempPath, this.lockPath); |
| 80 | } |
| 81 | |
| 82 | /** |
| 83 | * Read the lockfile and validate it. |
no test coverage detected