Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(109)

Side by Side Diff: pkg/scheduled_test/lib/scheduled_server.dart

Issue 12809002: Add a ScheduledServer class. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Code review changes Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | pkg/scheduled_test/lib/src/scheduled_server/handler.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 library scheduled_server;
6
7 import 'dart:async';
8 import 'dart:collection';
9 import 'dart:io';
10 import 'dart:uri';
11
12 import 'scheduled_test.dart';
13 import 'src/utils.dart';
14 import 'src/scheduled_server/handler.dart';
15
16 typedef Future ScheduledHandler(HttpRequest request);
17
18 /// A class representing an [HttpServer] that's scheduled to run in the course
19 /// of the test. This class allows the server's request handling to be scheduled
20 /// synchronously.
21 ///
22 /// The server expects requests to be received in the order [handle] is called,
23 /// and expects that no additional requests will be received.
24 class ScheduledServer {
25 /// The description of the server.
26 final String description;
27
28 /// The wrapped server.
29 final Future<HttpServer> _server;
30
31 /// The queue of handlers to run for upcoming requests. Each [Future] will
32 /// complete once the schedule reaches the point where that handler was
33 /// scheduled.
34 final _handlers = new Queue<Handler>();
35
36 /// The number of servers created. Used for auto-generating descriptions;
37 static var _count = 0;
38
39 ScheduledServer._(this._server, this.description);
40
41 /// Creates a new server listening on an automatically-allocated port on
42 /// localhost. [description] is used to refer to the server in debugging
43 /// messages.
44 factory ScheduledServer([String description]) {
45 var id = _count++;
46 if (description == null) description = 'scheduled server $id';
47
48 var scheduledServer;
49 scheduledServer = new ScheduledServer._(schedule(() {
50 return HttpServer.bind("127.0.0.1", 0).then((server) {
51 server.listen(scheduledServer._handleRequest,
52 onError: (e) => currentSchedule.signalError(e));
53 currentSchedule.onComplete.schedule(server.close);
54 return server;
55 });
56 }, "starting '$description'"), description);
57 return scheduledServer;
58 }
59
60 /// The port on which the server is listening.
61 Future<int> get port => _server.then((s) => s.port);
62
63 /// The base URL of the server, including its port.
64 Future<Uri> get url => port.then((p) => Uri.parse("http://localhost:$p"));
65
66 /// Schedules [handler] to handle a request to the server with [method] and
67 /// [path]. The schedule will wait until an HTTP request is received. If that
68 /// request doesn't have the expected [method] and [path], it will fail.
69 /// Otherwise, it will run [fn]. If [fn] returns a [Future], the schedule will
70 /// wait until that [Future] completes.
71 ///
72 /// The request must be received at the point in the schedule at which
73 /// [handle] was called, or in the task immediately prior (to allow for
74 /// non-deterministic asynchronicity). Otherwise, an error will be thrown.
75 void handle(String method, String path, ScheduledHandler fn) {
76 var handler = new Handler(this, method, path, fn);
77 _handlers.add(handler);
78 schedule(() {
79 handler.ready = true;
80 return handler.result.catchError((e) {
81 // Close the server so that we don't leave a dangling request.
82 _server.then((s) => s.close());
83 throw e;
84 });
85 }, "'$description' waiting for $method $path");
86 }
87
88 /// The handler for incoming [HttpRequest]s to this server. This dispatches
89 /// the request to the first handler in the queue. It's that handler's
90 /// responsibility to check that the method/path are correct and that it's
91 /// being run at the correct time.
92 void _handleRequest(HttpRequest request) {
93 wrapFuture(new Future.of(() {
94 if (_handlers.isEmpty) {
95 throw "'$description' received ${request.method} ${request.uri.path} "
96 "when no more requests were expected.";
97 }
98 return _handlers.removeFirst().fn(request);
99 }).catchError((e) {
100 // Close the server so that we don't leave a dangling request.
101 _server.then((s) => s.close());
102 throw e;
103 }), 'receiving ${request.method} ${request.uri}');
104 }
105 }
OLDNEW
« no previous file with comments | « no previous file | pkg/scheduled_test/lib/src/scheduled_server/handler.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698