setProtocol method

  1. @override
Future<void> setProtocol(
  1. ProtocolID protocol
)
override

Implementation

@override
Future<void> setProtocol(ProtocolID protocol) async {
  if (_protocolScopeImpl != null) {
    _logger.severe('$name: stream scope already attached to a protocol: ${_protocolScopeImpl!.protocol}');
    throw Exception('$name: stream scope already attached to a protocol: ${_protocolScopeImpl!.protocol}');
  }
  _logger.fine('$name: Setting protocol to $protocol for peer ${_peerScopeImpl.peer}');

  // 1. Get necessary scopes from ResourceManager
  final newProtocolScope = _rcmgr.getProtocolScopeInternal(protocol);
  final systemScope = _rcmgr.systemScope;
  final limiter = _rcmgr.limiter;

  // Explicitly cast to the concrete PeerId type
  final newPeerProtoScope = newProtocolScope.getPeerSubScope(
    _peerScopeImpl.peer as concrete_peer_id.PeerId,
    limiter,
    systemScope
  );

  // 2. Identify original transient scope
  // Initial edges for a stream are [peerScope, transientScope, systemScope]
  ResourceScopeImpl? transientScope;
  for (final edge in edges) {
    if (edge.name == 'transient' && edge is TransientScopeImpl) {
      transientScope = edge;
      break;
    }
  }
  if (transientScope == null) {
    _logger.fine('$name: Edges: ${edges.map((e) => e.name).join(', ')}');
    throw StateError('$name: Transient scope not found in initial edges for juggling.');
  }

  // 3. Move the stream from the transient scope under its peer-protocol
  // scope. reparent() counts it in the scopes it gains (the protocol and
  // peer-protocol scopes) and releases it from the transient scope; the
  // peer and system scopes keep counting it once.
  try {
    reparent([_peerScopeImpl, newPeerProtoScope]);
  } on network_errors.ResourceLimitExceededException catch (e) {
    _logger.fine('$name: Failed to reserve resources for protocol $protocol: $e.');
    rethrow;
  }
  _protocolScopeImpl = newProtocolScope;
  _peerProtoScope = newPeerProtoScope;
  _logger.fine('$name: Successfully set protocol to $protocol. Resources transferred, edges updated.');
}