claimPeerRun function

Future<PeerClaim> claimPeerRun(
  1. int projectId,
  2. String runTitle,
  3. Future<int> createRun(), {
  4. Map<String, String>? env,
})

Attaches to the shared run id, creating it on first claim.

createRun is called only by the first peer, inside the lock, so N peers never produce N runs. Rethrows whatever createRun throws.

Implementation

Future<PeerClaim> claimPeerRun(
  int projectId,
  String runTitle,
  Future<int> Function() createRun, {
  Map<String, String>? env,
}) async {
  final paths = handoffPaths(projectId, runTitle, env);
  if (!acquireHandoffLock(paths.lockPath, const Duration(seconds: 60))) {
    throw StateError(
      'Tracera: timed out waiting for handoff lock ${paths.lockPath}',
    );
  }
  try {
    final state = _readHandoffState(paths.idPath);
    if (state != null) {
      if (_handoffIdStale(paths.idPath)) {
        _tryDeleteFile(paths.idPath);
        logDebug(
          'Tracera: peer handoff .id file stale '
          '(>${handoffIdStaleAfter.inHours}h), creating a new run',
        );
      } else {
        if (!_tryWriteHandoffState(
          paths.idPath,
          state.runId,
          state.refs + 1,
          state.claimed + 1,
        )) {
          throw StateError(
            'Tracera: peer handoff could not write ${paths.idPath}',
          );
        }
        logDebug(
          'Tracera: peer handoff attach run #${state.runId} '
          '(refs=${state.refs + 1}, claimed=${state.claimed + 1})',
        );
        return PeerClaim(state.runId, false);
      }
    }
    final runId = await createRun();
    if (!_tryWriteHandoffState(paths.idPath, runId, 1, 1)) {
      throw StateError('Tracera: peer handoff could not write ${paths.idPath}');
    }
    logDebug('Tracera: peer handoff created run #$runId');
    return PeerClaim(runId, true);
  } finally {
    releaseHandoffLock(paths.lockPath);
  }
}