workspaceResidents function
Every process still WORKING somewhere under workspacePath, by current
directory.
bd forks detached children that outlive the command that spawned them —
bd send-metrics is the one measured here, born after a test body finished
and alive for ~25 seconds afterwards. They carry no --config or --root,
so workspaceStoreProcesses cannot see them, and they inherit the
workspace as their working directory, which is the only mark they leave in
the process table.
They are why a SIGKILL fence can run its full bound and still find a proxy:
a live bd client re-spawns one to serve itself every time the fence kills
the last. Killing them is also what stops a straggler from writing the
store back into existence AFTER a delete that already reported success.
lsof is the only account of a working directory on this platform. If it
is absent or refuses, this degrades to the store census alone — the
behaviour that shipped before — and a bounded delete absorbs the
difference. runProcess and selfPid are injected so both that
degradation and the parse are provable without a store to point them at.
Implementation
Future<List<int>> workspaceResidents(
String workspacePath, {
required int selfPid,
required Future<ProcessResult> Function(String, List<String>) runProcess,
}) async {
final ProcessResult result;
try {
result = await runProcess('lsof', [
'-w',
'-a',
'-d',
'cwd',
'-Fp',
'+D',
workspacePath,
]);
} on ProcessException {
return const [];
}
return parseLsofPids(result.stdout as String, selfPid: selfPid);
}