Skip to content

Commit

Permalink
Fix an uncaught exception during dart startup (#3640)
Browse files Browse the repository at this point in the history
Here's an example of the error output from before this change:

Unhandled exception:
Bad state: Stream was already listened to
#0      _RawServerSocket.listen (dart:io-patch/socket_patch.dart:1106)
#1      new _ForwardingStreamSubscription (dart:async/stream_pipe.dart:123)
#2      _ForwardingStream._createSubscription (dart:async/stream_pipe.dart:91)
#3      _ForwardingStream.listen (dart:async/stream_pipe.dart:86)
#4      _ServerSocket.listen (dart:io-patch/socket_patch.dart:1351)
#5      _HttpServer.listen (dart:io/http_impl.dart:2278)
#6      _startServer.<anonymous closure> (file:///server.dart:88:12)
#7      _RootZone.runUnary (dart:async/zone.dart:1371)
#8      _FutureListener.handleValue (dart:async/future_impl.dart:129)
#9      _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:636)
#10     _Future._propagateToListeners (dart:async/future_impl.dart:665)
#11     _Future._completeWithValue (dart:async/future_impl.dart:478)
#12     Future.wait.<anonymous closure> (dart:async/future.dart:362)
#13     _RootZone.runUnary (dart:async/zone.dart:1371)
#14     _FutureListener.handleValue (dart:async/future_impl.dart:129)
#15     _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:636)
#16     _Future._propagateToListeners (dart:async/future_impl.dart:665)
#17     _Future._completeWithValue (dart:async/future_impl.dart:478)
#18     Future.wait.<anonymous closure> (dart:async/future.dart:362)
#19     _RootZone.runUnary (dart:async/zone.dart:1371)
#20     _FutureListener.handleValue (dart:async/future_impl.dart:129)
#21     _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:636)
#22     _Future._propagateToListeners (dart:async/future_impl.dart:665)
#23     _Future._completeWithValue (dart:async/future_impl.dart:478)
#24     _Future._asyncComplete.<anonymous closure> (dart:async/future_impl.dart:510)
#25     _microtaskLoop (dart:async/schedule_microtask.dart:41)
#26     _startMicrotaskLoop (dart:async/schedule_microtask.dart:50)
#27     _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:99)
#28     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:152)
  • Loading branch information
michaelhixson authored and NateBrady23 committed Apr 24, 2018
1 parent a0776f5 commit 04dd98d
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 30 deletions.
8 changes: 6 additions & 2 deletions frameworks/Dart/dart/dart.dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
FROM google/dart:1.24

COPY ./ ./
WORKDIR /dart_app
COPY fortunes.mustache fortunes.mustache
COPY postgresql.yaml postgresql.yaml
COPY pubspec.yaml pubspec.yaml
COPY server.dart server.dart

RUN pub upgrade

CMD dart server.dart -a 0.0.0.0 -p 8080 -i $(nproc)
CMD ["dart", "server.dart"]
2 changes: 1 addition & 1 deletion frameworks/Dart/dart/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ description: A benchmark of dart
environment:
sdk: '>=1.6.0 <2.0.0'
dependencies:
args: 0.12.0+2
crypto: 0.9.0
mustache: 0.1.8
postgresql: 0.2.14
system_info: 0.0.16
yaml: 2.0.1+1
48 changes: 21 additions & 27 deletions frameworks/Dart/dart/server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,30 @@ import 'dart:async' show Future;
import 'dart:convert';
import 'dart:io';
import 'dart:isolate';
import 'dart:math' show Random;
import 'package:args/args.dart' show ArgParser;
import 'dart:math' show Random, max;
import 'package:mustache/mustache.dart' as mustache;
import 'package:postgresql/postgresql.dart' as pg;
import 'package:postgresql/postgresql_pool.dart' as pgpool;
import 'package:system_info/system_info.dart';
import 'package:yaml/yaml.dart' as yaml;

final _NUM_PROCESSORS = SysInfo.processors.length;

final _encoder = new JsonUtf8Encoder();

/// Starts a new HTTP server that implements the tests to be benchmarked. The
/// address and port for incoming connections is configurable via command line
/// arguments, as is the number of database connections to be maintained in the
/// connection pool.
void main(List<String> args) {
var parser = new ArgParser()
..addOption('address', abbr: 'a', defaultsTo: '0.0.0.0')
..addOption('port', abbr: 'p', defaultsTo: '8080')
..addOption('dbconnections', abbr: 'd', defaultsTo: '256')
..addOption('isolates', abbr: 'i', defaultsTo: '1');
var arguments = parser.parse(args);
var isolates = int.parse(arguments['isolates']);
var dbConnections = int.parse(arguments['dbconnections']) ~/ isolates;
ServerSocket
.bind(arguments['address'], int.parse(arguments['port']), shared: true)
.then((server) {
for (int i = 1; i < isolates; i++) {
_startServer(server, dbConnections);
}
});
ReceivePort errorPort = new ReceivePort();
errorPort.listen((e) => print(e));
for (int i = 0; i < _NUM_PROCESSORS; i++) {
Isolate.spawn(
startInIsolate,
[],
onError: errorPort.sendPort);
}
}

void startInIsolate(List args) {
_startServer();
}

/// The entity used in the database query and update tests.
Expand Down Expand Up @@ -67,11 +62,10 @@ pgpool.Pool _connectionPool;
/// The mustache template which is rendered in the fortunes test.
mustache.Template _fortunesTemplate;

/// Starts a benchmark server, which listens for connections from
/// '[address] : [port]' and maintains [dbConnections] connections to the
/// database.
void _startServer(serverSocket, dbConnections) {
void _startServer() {
var dbConnections = max(1, (256 / _NUM_PROCESSORS).floor());
Future.wait([
HttpServer.bind("0.0.0.0", 8080, shared: true),
new File('postgresql.yaml').readAsString().then((config) {
_connectionPool = new pgpool.Pool(
new pg.Settings.fromMap(yaml.loadYaml(config)).toUri(),
Expand All @@ -81,8 +75,8 @@ void _startServer(serverSocket, dbConnections) {
new File('fortunes.mustache').readAsString().then((template) {
_fortunesTemplate = mustache.parse(template);
})
]).then((_) {
var server = new HttpServer.listenOn(serverSocket);
]).then((List waitResults) {
var server = waitResults[0];
server.defaultResponseHeaders.clear();
server.serverHeader = 'dart';
server.listen((request) {
Expand Down

0 comments on commit 04dd98d

Please sign in to comment.