Skip to content
Snippets Groups Projects
Commit 76069d4f authored by Natalie Weizenbaum's avatar Natalie Weizenbaum
Browse files

Make BrowserManager resilient to an early exit.

This also reverts the MultiChannel commits that were causing timeouts.

R=kevmoo@google.com

Review URL: https://codereview.chromium.org//1062943005
parent 525e4b30
No related branches found
No related tags found
No related merge requests found
......@@ -50,7 +50,12 @@ class BrowserManager {
// Create a nested MultiChannel because the iframe will be using a channel
// wrapped within the host's channel.
suiteChannel = new MultiChannel(suiteChannel.stream, suiteChannel.sink);
return suiteChannel.stream.first.then((response) {
// The stream may close before emitting a value if the browser is killed
// prematurely (e.g. via Control-C).
return maybeFirst(suiteChannel.stream).then((response) {
if (response == null) return null;
if (response["type"] == "loadException") {
return new Future.error(new LoadException(path, response["message"]));
} else if (response["type"] == "error") {
......
......@@ -93,9 +93,6 @@ class _MultiChannel extends StreamChannelMixin implements MultiChannel {
/// The subscription to [_innerStream].
StreamSubscription _innerStreamSubscription;
/// Whether this channel has been closed.
bool _closed = false;
Stream get stream => _streamController.stream;
final _streamController = new StreamController(sync: true);
......@@ -201,9 +198,6 @@ class _MultiChannel extends StreamChannelMixin implements MultiChannel {
/// Closes the virtual channel for which incoming messages have [inputId] and
/// outgoing messages have [outputId].
void _closeChannel(int inputId, int outputId) {
if (_closed) return;
_closed = inputId == 0;
// A message without data indicates that the virtual channel has been
// closed.
_streamControllers.remove(inputId).close();
......
......@@ -184,6 +184,25 @@ Stream mergeStreams(Iterable<Stream> streamIter) {
return controller.stream;
}
/// Returns the first value [stream] emits, or `null` if [stream] closes before
/// emitting a value.
Future maybeFirst(Stream stream) {
var completer = new Completer();
var subscription;
subscription = stream.listen((data) {
completer.complete(data);
subscription.cancel();
}, onError: (error, stackTrace) {
completer.completeError(error, stackTrace);
subscription.cancel();
}, onDone: () {
completer.complete();
});
return completer.future;
}
/// Returns a random base64 string containing [bytes] bytes of data.
///
/// [seed] is passed to [math.Random]; [urlSafe] and [addLineSeparator] are
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment