LCOV - code coverage report
Current view: top level - stream_channel-2.1.0/lib/src - isolate_channel.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 11 28 39.3 %
Date: 2021-11-28 14:37:50 Functions: 0 0 -

          Line data    Source code
       1             : // Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
       2             : // for details. All rights reserved. Use of this source code is governed by a
       3             : // BSD-style license that can be found in the LICENSE file.
       4             : 
       5             : import 'dart:async';
       6             : import 'dart:isolate';
       7             : 
       8             : import 'package:async/async.dart';
       9             : 
      10             : import '../stream_channel.dart';
      11             : 
      12             : /// A [StreamChannel] that communicates over a [ReceivePort]/[SendPort] pair,
      13             : /// presumably with another isolate.
      14             : ///
      15             : /// The remote endpoint doesn't necessarily need to be running an
      16             : /// [IsolateChannel]. This can be used with any two ports, although the
      17             : /// [StreamChannel] semantics mean that this class will treat them as being
      18             : /// paired (for example, closing the [sink] will cause the [stream] to stop
      19             : /// emitting events).
      20             : ///
      21             : /// The underlying isolate ports have no notion of closing connections. This
      22             : /// means that [stream] won't close unless [sink] is closed, and that closing
      23             : /// [sink] won't cause the remote endpoint to close. Users should take care to
      24             : /// ensure that they always close the [sink] of every [IsolateChannel] they use
      25             : /// to avoid leaving dangling [ReceivePort]s.
      26             : class IsolateChannel<T> extends StreamChannelMixin<T> {
      27             :   @override
      28             :   final Stream<T> stream;
      29             :   @override
      30             :   final StreamSink<T> sink;
      31             : 
      32             :   /// Connects to a remote channel that was created with
      33             :   /// [IsolateChannel.connectSend].
      34             :   ///
      35             :   /// These constructors establish a connection using only a single
      36             :   /// [SendPort]/[ReceivePort] pair, as long as each side uses one of the
      37             :   /// connect constructors.
      38             :   ///
      39             :   /// The connection protocol is guaranteed to remain compatible across versions
      40             :   /// at least until the next major version release. If the protocol is
      41             :   /// violated, the resulting channel will emit a single value on its stream and
      42             :   /// then close.
      43           0 :   factory IsolateChannel.connectReceive(ReceivePort receivePort) {
      44             :     // We can't use a [StreamChannelCompleter] here because we need the return
      45             :     // value to be an [IsolateChannel].
      46           0 :     var streamCompleter = StreamCompleter<T>();
      47           0 :     var sinkCompleter = StreamSinkCompleter<T>();
      48             :     var channel =
      49           0 :         IsolateChannel<T>._(streamCompleter.stream, sinkCompleter.sink);
      50             : 
      51             :     // The first message across the ReceivePort should be a SendPort pointing to
      52             :     // the remote end. If it's not, we'll make the stream emit an error
      53             :     // complaining.
      54             :     late StreamSubscription<dynamic> subscription;
      55           0 :     subscription = receivePort.listen((message) {
      56           0 :       if (message is SendPort) {
      57             :         var controller =
      58           0 :             StreamChannelController<T>(allowForeignErrors: false, sync: true);
      59           0 :         SubscriptionStream(subscription).cast<T>().pipe(controller.local.sink);
      60           0 :         controller.local.stream
      61           0 :             .listen((data) => message.send(data), onDone: receivePort.close);
      62             : 
      63           0 :         streamCompleter.setSourceStream(controller.foreign.stream);
      64           0 :         sinkCompleter.setDestinationSink(controller.foreign.sink);
      65             :         return;
      66             :       }
      67             : 
      68           0 :       streamCompleter.setError(
      69           0 :           StateError('Unexpected Isolate response "$message".'),
      70           0 :           StackTrace.current);
      71           0 :       sinkCompleter.setDestinationSink(NullStreamSink<T>());
      72           0 :       subscription.cancel();
      73             :     });
      74             : 
      75             :     return channel;
      76             :   }
      77             : 
      78             :   /// Connects to a remote channel that was created with
      79             :   /// [IsolateChannel.connectReceive].
      80             :   ///
      81             :   /// These constructors establish a connection using only a single
      82             :   /// [SendPort]/[ReceivePort] pair, as long as each side uses one of the
      83             :   /// connect constructors.
      84             :   ///
      85             :   /// The connection protocol is guaranteed to remain compatible across versions
      86             :   /// at least until the next major version release.
      87          11 :   factory IsolateChannel.connectSend(SendPort sendPort) {
      88          11 :     var receivePort = ReceivePort();
      89          22 :     sendPort.send(receivePort.sendPort);
      90          11 :     return IsolateChannel(receivePort, sendPort);
      91             :   }
      92             : 
      93             :   /// Creates a stream channel that receives messages from [receivePort] and
      94             :   /// sends them over [sendPort].
      95          11 :   factory IsolateChannel(ReceivePort receivePort, SendPort sendPort) {
      96             :     var controller =
      97          11 :         StreamChannelController<T>(allowForeignErrors: false, sync: true);
      98          44 :     receivePort.cast<T>().pipe(controller.local.sink);
      99          22 :     controller.local.stream
     100          44 :         .listen((data) => sendPort.send(data), onDone: receivePort.close);
     101          55 :     return IsolateChannel._(controller.foreign.stream, controller.foreign.sink);
     102             :   }
     103             : 
     104          11 :   IsolateChannel._(this.stream, this.sink);
     105             : }

Generated by: LCOV version 1.14