1ef4399df0
This uses optional new/const and `=` in named argument defaults. All changes are automated, except for: - utils/dartdevc/BUILD.gn: run DDC build scripts with --preview-dart-2 - pkg/dev_compiler/tool/patch_sdk.dart: add a TODO that Analyzer doesn't supporting implicit const in libraries.dart - pkg/dev_compiler/tool/input_sdk/libraries.dart: was not formatted due to the aforementioned Analyzer bug - tools/bots/test_matrix.json: run DDC sourcemap suite in Dart 2 mode - pkg/pkg.status: skip pkg/dev_compiler if running in Dart 1 mode Change-Id: I9b80ccba0c2cc7b66efc662a0b16562e3660aee3 Reviewed-on: https://dart-review.googlesource.com/60402 Commit-Queue: Jenny Messerly <jmesserly@google.com> Reviewed-by: Bob Nystrom <rnystrom@google.com>
84 lines
2.5 KiB
Dart
84 lines
2.5 KiB
Dart
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
import 'dart:io';
|
|
import 'dart:async';
|
|
|
|
class ChildServerProcess {
|
|
/// [IOSink]s like [stdout] don't like to be piped more than one [Stream], but
|
|
/// we want to pipe many of them (basically, every standard output and error
|
|
/// of every child process we open), so we pipe to an accommodating consumer.
|
|
static final _consoleOut = _MultipleStreamConsumer(stdout);
|
|
|
|
final Process process;
|
|
final String host;
|
|
final int port;
|
|
ChildServerProcess._(this.process, this.host, this.port);
|
|
|
|
get httpUri => Uri.parse('http://$host:$port');
|
|
|
|
static build(Future<Process> builder(String host, int port),
|
|
{int defaultPort = 1024,
|
|
int maxPort = 65535,
|
|
String host = '0.0.0.0'}) async {
|
|
var port = await _findUnusedPort(defaultPort, maxPort);
|
|
var p = (await builder(host, port))
|
|
..stdout.pipe(_consoleOut)
|
|
..stderr.pipe(_consoleOut);
|
|
await _waitForServer(host, port);
|
|
return ChildServerProcess._(p, host, port);
|
|
}
|
|
|
|
static _waitForServer(String host, int port,
|
|
{int attempts = 10,
|
|
Duration retryDelay = const Duration(seconds: 1)}) async {
|
|
var lastError;
|
|
for (int i = 0; i < attempts; i++) {
|
|
try {
|
|
await (await Socket.connect(host, port)).close();
|
|
return;
|
|
} catch (e) {
|
|
lastError = e;
|
|
await Future.delayed(retryDelay);
|
|
}
|
|
}
|
|
throw StateError(
|
|
'Failed to connect to $host:$port after $attempts attempts; '
|
|
'Last error:\n$lastError');
|
|
}
|
|
|
|
static Future<int> _findUnusedPort(int fromPort, int toPort) async {
|
|
var lastError;
|
|
for (int port = fromPort; port <= toPort; port++) {
|
|
try {
|
|
await (await ServerSocket.bind(InternetAddress.ANY_IP_V4, port))
|
|
.close();
|
|
return port;
|
|
} catch (e) {
|
|
lastError = e;
|
|
}
|
|
}
|
|
throw StateError(
|
|
'Failed to find an unused port between $fromPort and $toPort; '
|
|
'Last error:\n$lastError');
|
|
}
|
|
}
|
|
|
|
/// A consumer into which we can pipe as many streams as we want, that forwards
|
|
/// everything to an [IOSink] (such as [stdout]).
|
|
class _MultipleStreamConsumer extends StreamConsumer<List<int>> {
|
|
final IOSink _sink;
|
|
_MultipleStreamConsumer(this._sink);
|
|
|
|
@override
|
|
Future addStream(Stream<List<int>> stream) async {
|
|
await for (var data in stream) {
|
|
_sink.add(data);
|
|
}
|
|
}
|
|
|
|
@override
|
|
close() {}
|
|
}
|