setProtocol method
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.');
}