Index: example/http_server.dart |
diff --git a/example/http_server.dart b/example/http_server.dart |
index 2a964786afec7dfc003caa97c78ec5386d81f8e0..92ca9c71901afe043c21cd7dd7d7f24bfe0ca423 100644 |
--- a/example/http_server.dart |
+++ b/example/http_server.dart |
@@ -15,25 +15,24 @@ import "package:isolate/runner.dart"; |
typedef Future RemoteStop(); |
Future<RemoteStop> runHttpServer( |
- Runner runner, ServerSocket socket, HttpListener listener) { |
- return runner.run(_startHttpServer, new List(2)..[0] = socket.reference |
- ..[1] = listener) |
- .then((SendPort stopPort) => () => _sendStop(stopPort)); |
-} |
+ Runner runner, int port, HttpListener listener) async { |
+ var stopPort = await runner.run(_startHttpServer, [port, listener]); |
-Future _sendStop(SendPort stopPort) { |
- return singleResponseFuture(stopPort.send); |
+ return () => _sendStop(stopPort); |
} |
-Future<SendPort> _startHttpServer(List args) { |
- ServerSocketReference ref = args[0]; |
+Future _sendStop(SendPort stopPort) => singleResponseFuture(stopPort.send); |
+ |
+Future<SendPort> _startHttpServer(List args) async { |
+ int port = args[0]; |
HttpListener listener = args[1]; |
- return ref.create().then((socket) { |
- return listener.start(new HttpServer.listenOn(socket)); |
- }).then((_) { |
- return singleCallbackPort((SendPort resultPort) { |
- sendFutureResult(new Future.sync(listener.stop), resultPort); |
- }); |
+ |
+ var server = |
+ await HttpServer.bind(InternetAddress.ANY_IP_V6, port, shared: true); |
+ await listener.start(server); |
+ |
+ return singleCallbackPort((SendPort resultPort) { |
+ sendFutureResult(new Future.sync(listener.stop), resultPort); |
}); |
} |
@@ -52,65 +51,79 @@ abstract class HttpListener { |
/// Returns the message content plus an ID describing the isolate that |
/// handled the request. |
class EchoHttpListener implements HttpListener { |
+ static const _delay = const Duration(seconds: 2); |
+ static final _id = Isolate.current.hashCode; |
+ final SendPort _counter; |
+ |
StreamSubscription _subscription; |
- static int _id = new Object().hashCode; |
- SendPort _counter; |
EchoHttpListener(this._counter); |
- start(HttpServer server) { |
+ Future start(HttpServer server) async { |
print("Starting isolate $_id"); |
- _subscription = server.listen((HttpRequest request) { |
- request.response.addStream(request).then((_) { |
- _counter.send(null); |
- print("Request to $_id"); |
- request.response.write("#$_id\n"); |
- var t0 = new DateTime.now().add(new Duration(seconds: 2)); |
- while (new DateTime.now().isBefore(t0)); |
- print("Response from $_id"); |
- request.response.close(); |
- }); |
+ _subscription = server.listen((HttpRequest request) async { |
+ await request.response.addStream(request); |
+ print("Request to $hashCode"); |
+ request.response.write("#$_id\n"); |
+ var watch = new Stopwatch()..start(); |
+ while (watch.elapsed < _delay); |
+ print("Response from $_id"); |
+ await request.response.close(); |
+ _counter.send(null); |
}); |
} |
- stop() { |
+ Future stop() async { |
print("Stopping isolate $_id"); |
- _subscription.cancel(); |
+ await _subscription.cancel(); |
_subscription = null; |
} |
} |
-main(args) { |
+main(List<String> args) async { |
int port = 0; |
if (args.length > 0) { |
port = int.parse(args[0]); |
} |
- RawReceivePort counter = new RawReceivePort(); |
+ |
+ var counter = new ReceivePort(); |
HttpListener listener = new EchoHttpListener(counter.sendPort); |
- ServerSocket |
- .bind(InternetAddress.ANY_IP_V6, port) |
- .then((ServerSocket socket) { |
- port = socket.port; |
- return Future.wait(new Iterable.generate(5, (_) => IsolateRunner.spawn()), |
- cleanUp: (isolate) { isolate.close(); }) |
- .then((List<IsolateRunner> isolates) { |
- return Future.wait(isolates.map((IsolateRunner isolate) { |
- return runHttpServer(isolate, socket, listener); |
- }), cleanUp: (server) { server.stop(); }); |
- }) |
- .then((stoppers) { |
- socket.close(); |
- int count = 25; |
- counter.handler = (_) { |
- count--; |
- if (count == 0) { |
- stoppers.forEach((f) => f()); |
- counter.close(); |
- } |
- }; |
- print("Server listening on port $port for 25 requests"); |
- print("Test with:"); |
- print(" ab -c10 -n 25 http://localhost:$port/"); |
- }); |
+ |
+ // Used to ensure the requested port is available or to find an available |
+ // port if `0` is provided. |
+ ServerSocket socket = |
+ await ServerSocket.bind(InternetAddress.ANY_IP_V6, port, shared: true); |
+ |
+ port = socket.port; |
+ var isolates = await Future.wait( |
+ new Iterable.generate(5, (_) => IsolateRunner.spawn()), |
+ cleanUp: (isolate) { |
+ isolate.close(); |
+ }); |
+ |
+ List<RemoteStop> stoppers = await Future.wait(isolates |
+ .map((IsolateRunner isolate) { |
+ return runHttpServer(isolate, socket.port, listener); |
+ }), cleanUp: (server) { |
+ server.stop(); |
}); |
+ |
+ await socket.close(); |
+ int count = 25; |
+ |
+ print("Server listening on port $port for $count requests"); |
+ print("Test with:"); |
+ print(" ab -l -c10 -n $count http://localhost:$port/"); |
+ |
+ await for (var event in counter) { |
+ count--; |
+ if (count == 0) { |
+ print('Shutting down'); |
+ for (var stopper in stoppers) { |
+ await stopper(); |
+ } |
+ counter.close(); |
+ } |
+ } |
+ print('Finished'); |
} |