| Index: lib/src/runner/browser/browser_manager.dart
|
| diff --git a/lib/src/runner/browser/browser_manager.dart b/lib/src/runner/browser/browser_manager.dart
|
| index b20da07929044e06b7455a434c05cc5e05378c18..3193a8015e2108eb14ff1ed2173bc32c85497787 100644
|
| --- a/lib/src/runner/browser/browser_manager.dart
|
| +++ b/lib/src/runner/browser/browser_manager.dart
|
| @@ -8,6 +8,7 @@ import 'dart:async';
|
| import 'dart:convert';
|
|
|
| import 'package:http_parser/http_parser.dart';
|
| +import 'package:pool/pool.dart';
|
|
|
| import '../../backend/metadata.dart';
|
| import '../../backend/suite.dart';
|
| @@ -31,6 +32,15 @@ class BrowserManager {
|
| /// This is connected to a page running `static/host.dart`.
|
| final MultiChannel _channel;
|
|
|
| + /// A pool that ensures that limits the number of initial connections the
|
| + /// manager will wait for at once.
|
| + ///
|
| + /// This isn't the *total* number of connections; any number of iframes may be
|
| + /// loaded in the same browser. However, the browser can only load so many at
|
| + /// once, and we want a timeout in case they fail so we only wait for so many
|
| + /// at once.
|
| + final _pool = new Pool(8);
|
| +
|
| /// Creates a new BrowserManager that communicates with [browser] over
|
| /// [webSocket].
|
| BrowserManager(this.browser, CompatibleWebSocket webSocket)
|
| @@ -49,25 +59,27 @@ class BrowserManager {
|
| "browser": browser.identifier
|
| })));
|
|
|
| + // The stream may close before emitting a value if the browser is killed
|
| + // prematurely (e.g. via Control-C).
|
| var suiteChannel = _channel.virtualChannel();
|
| - _channel.sink.add({
|
| - "command": "loadSuite",
|
| - "url": url.toString(),
|
| - "channel": suiteChannel.id
|
| - });
|
| + return _pool.withResource(() {
|
| + _channel.sink.add({
|
| + "command": "loadSuite",
|
| + "url": url.toString(),
|
| + "channel": suiteChannel.id
|
| + });
|
|
|
| - // 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);
|
| + // 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);
|
|
|
| - // The stream may close before emitting a value if the browser is killed
|
| - // prematurely (e.g. via Control-C).
|
| - return maybeFirst(suiteChannel.stream)
|
| - .timeout(new Duration(seconds: 7), onTimeout: () {
|
| - throw new LoadException(
|
| - path,
|
| - "Timed out waiting for the test suite to connect on "
|
| - "${browser.name}.");
|
| + return maybeFirst(suiteChannel.stream)
|
| + .timeout(new Duration(seconds: 15), onTimeout: () {
|
| + throw new LoadException(
|
| + path,
|
| + "Timed out waiting for the test suite to connect on "
|
| + "${browser.name}.");
|
| + });
|
| }).then((response) {
|
| if (response == null) return null;
|
|
|
|
|