// Proves the single-daemon-per-storage guard primitive (index.js): the advisory
// flock on <storage>/keet-daemon.lock must (1) be acquirable by the first daemon,
// (2) REFUSE a second acquirer on the same storage (the stortron --dedicated
// contention that wedged keet-core with "Autobase is closing"), (3) expose the
// holder PID for the refusal message, and (4) auto-release when the holder's fd
// closes (process exit / SIGKILL) so no stale guard blocks a restart.
// fs-native-extensions.tryLock is BSD-flock (verified: same-inode locks conflict
// across fds and release on close), so this is faithful single-process.
import fs from 'bare-fs'
import fsx from 'fs-native-extensions'
import path from 'bare-path'
import os from 'bare-os'
const dir = path.join(os.tmpdir(), 'keet-single-lock-' + Bare.pid)
fs.mkdirSync(dir, { recursive: true })
const lockPath = path.join(dir, 'keet-daemon.lock')
let pass = 0; let fail = 0
const ok = (c, m) => { if (c) { pass++; console.log(' ok ' + m) } else { fail++; console.log(' FAIL ' + m) } }
// Mirrors the guard in index.js: open 'a+', tryLock, write PID on success.
function acquire () {
const fd = fs.openSync(lockPath, 'a+')
if (!fsx.tryLock(fd)) { try { fs.closeSync(fd) } catch {}; return null }
fs.writeFileSync(lockPath, String(1000 + pass))
return fd
}
async function main () {
// 1. First daemon acquires.
const fd1 = acquire()
ok(fd1 !== null, '1. first daemon acquires the storage lock')
// 2. Second daemon on the SAME storage is refused (no wedge).
const fd2 = acquire()
ok(fd2 === null, '2. second daemon on same storage is REFUSED')
// 3. Holder PID is readable for the refusal diagnostic.
const holder = fs.readFileSync(lockPath, 'utf8').trim()
ok(holder.length > 0, '3. holder PID readable for the refusal message (got "' + holder + '")')
// 4. Holder exits (fd close == process death) → lock FREE, no stale guard.
try { fsx.unlock(fd1) } catch {}; fs.closeSync(fd1)
const fd3 = acquire()
ok(fd3 !== null, '4. after holder exits, lock is FREE — a restart is not blocked')
if (fd3) { try { fsx.unlock(fd3) } catch {}; fs.closeSync(fd3) }
fs.rmSync(dir, { recursive: true, force: true })
console.log('\n[probe] pass=' + pass + ' fail=' + fail)
Bare.exit(fail ? 1 : 0)
}
main().catch((e) => { console.error('[probe] THREW:', e && e.stack ? e.stack : e); Bare.exit(2) })