releasePeerRun function
Drops one participant; the last expected peer calls finish.
With peerCountEnv set, the run is held open while fewer peers have claimed than expected, so a late starter still attaches.
Implementation
Future<void> releasePeerRun(
int projectId,
String runTitle,
Future<void> Function() finish, {
Map<String, String>? env,
}) async {
final paths = handoffPaths(projectId, runTitle, env);
try {
if (!File(paths.idPath).existsSync()) return;
} on IOException {
return;
}
if (!acquireHandoffLock(paths.lockPath, const Duration(seconds: 60))) {
logDebug('Tracera: timed out waiting for handoff lock ${paths.lockPath}');
return;
}
try {
final state = _readHandoffState(paths.idPath);
if (state == null) return;
var refs = state.refs - 1;
if (refs < 0) refs = 0;
if (refs > 0) {
// Ignore write failure — same as Go `_ = writeHandoffState`.
_tryWriteHandoffState(paths.idPath, state.runId, refs, state.claimed);
logDebug(
'Tracera: peer handoff release run #${state.runId} (refs=$refs)',
);
return;
}
final expected = peerCount(env);
if (expected > 0 && state.claimed < expected) {
_tryWriteHandoffState(paths.idPath, state.runId, refs, state.claimed);
logDebug(
'Tracera: peer handoff holding run #${state.runId} open '
'(claimed=${state.claimed}/$expected, waiting for peers)',
);
return;
}
await finish();
_tryDeleteFile(paths.idPath);
logDebug('Tracera: peer handoff finished run #${state.runId}');
} finally {
releaseHandoffLock(paths.lockPath);
}
}