Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions dwds/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 11.2.1-dev

- Recover from used port errors when starting debug service.

## 11.2.0

- Throw `SentinelException` instead of `RPCError` on vm service
Expand Down
6 changes: 2 additions & 4 deletions dwds/lib/src/services/debug_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import 'dart:math';
import 'dart:typed_data';

import 'package:dds/dds.dart';
import 'package:http_multi_server/http_multi_server.dart';
import 'package:pedantic/pedantic.dart';
import 'package:shelf/shelf.dart' as shelf;
import 'package:shelf/shelf.dart' hide Response;
Expand Down Expand Up @@ -253,13 +252,12 @@ class DebugService {
return innerHandler(request);
};
}
var port = await findUnusedPort();
var server = await HttpMultiServer.bind(hostname, port);
var server = await startHttpServer(hostname);
serveRequests(server, handler);
return DebugService._(
chromeProxyService,
server.address.host,
port,
server.port,
authToken,
serviceExtensionRegistry,
server,
Expand Down
23 changes: 23 additions & 0 deletions dwds/lib/src/utilities/shared.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import 'dart:io';

import 'package:http_multi_server/http_multi_server.dart';
import 'package:vm_service/vm_service.dart';
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';

Expand Down Expand Up @@ -47,6 +48,28 @@ Future<int> findUnusedPort() async {
return port;
}

/// Finds unused port and binds a new http server to it.
///
/// Retries a few times to recover from errors due to
/// another thread or process opening the same port.
Future<HttpServer> startHttpServer(String hostname, {int port}) async {
HttpServer httpServer;
var retries = 5;
var i = 0;
while (i < retries) {
i++;
try {
httpServer =
await HttpMultiServer.bind(hostname, port ?? await findUnusedPort());
} on SocketException {
if (i == retries) rethrow;
}
if (httpServer != null || i == retries) return httpServer;
await Future<void>.delayed(const Duration(milliseconds: 100));
}
return httpServer;
}

/// Throws an [ExceptionDetails] object if `exceptionDetails` is present on the
/// result.
void handleErrorIfPresent(WipResponse response,
Expand Down
2 changes: 1 addition & 1 deletion dwds/lib/src/version.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dwds/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: dwds
# Every time this changes you need to run `pub run build_runner build`.
version: 11.2.0
version: 11.2.1-dev
homepage: https://github.com/dart-lang/webdev/tree/master/dwds
description: >-
A service that proxies between the Chrome debug protocol and the Dart VM
Expand Down
7 changes: 4 additions & 3 deletions dwds/test/expression_compiler_service_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import 'dart:io';

import 'package:dwds/dwds.dart';
import 'package:dwds/src/utilities/shared.dart';
import 'package:http_multi_server/http_multi_server.dart';
import 'package:path/path.dart' as p;
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as shelf_io;
Expand Down Expand Up @@ -54,8 +53,11 @@ void main() async {
{loggerName, error, stackTrace, verbose}) =>
output.add('[$level] $loggerName: $message'));

// start asset server
server = await startHttpServer('localhost');
var port = server.port;

// start expression compilation service
final port = await findUnusedPort();
final assetHandler = (request) =>
Response(200, body: File.fromUri(kernel).readAsBytesSync());
service =
Expand All @@ -64,7 +66,6 @@ void main() async {
await service.initialize(moduleFormat: 'amd');

// setup asset server
server = await HttpMultiServer.bind('localhost', port);
shelf_io.serveRequests(
server, Cascade().add(service.handler).add(assetHandler).handler);

Expand Down