generateId method
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;
}