generateId method

int generateId()

Generates a new unique stream ID.

Throws if the maximum ID is reached and no reusable IDs exist.

Implementation

int generateId() {
  // +2, not +1: the two roles own opposite parities of the id space.
  final nextId = _lastId + 2;

  if (nextId <= _maxAssignableId) {
    _lastId = _lastIssued = nextId;
    _activeIds.add(nextId);
    return nextId;
  }

  // Nothing in flight, so the whole range is free again.
  if (_activeIds.isEmpty) {
    final restartId = _firstAssignableId;
    _lastId = _lastIssued = restartId;
    _activeIds.add(restartId);
    return restartId;
  }

  final recycledId = _findReusableId();
  if (recycledId == null) {
    // RESOURCE_EXHAUSTED: a limit that frees up, which is what gRPC answers
    // for stream exhaustion and what makes it retryable.
    throw RpcStatusException.atCapacity(
      'All $_sideLabel Stream IDs are in use. '
      'Wait for active streams to finish or establish a new connection.',
    );
  }

  _activeIds.add(recycledId);
  _lastIssued = recycledId;
  return recycledId;
}