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

Side by Side Diff: dart/pkg/dart2js_incremental/lib/server.dart

Issue 847573003: Push updates to browser. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Update package:browser version. Created 5 years, 11 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 | « dart/pkg/dart2js_incremental/lib/dart2js_incremental.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library dart2js_incremental.server; 5 library dart2js_incremental.server;
6 6
7 import 'dart:io'; 7 import 'dart:io';
8 8
9 import 'dart:async' show 9 import 'dart:async' show
10 Completer, 10 Completer,
11 Future, 11 Future,
12 Stream, 12 Stream,
13 StreamController,
13 StreamSubscription; 14 StreamSubscription;
14 15
15 import 'dart:convert' show 16 import 'dart:convert' show
16 HtmlEscape, 17 HtmlEscape,
17 JSON, 18 JSON,
18 UTF8; 19 UTF8;
19 20
20 import 'src/options.dart'; 21 import 'src/options.dart';
21 22
22 import 'compiler.dart' show 23 import 'compiler.dart' show
23 CompilerEvent, 24 CompilerEvent,
24 IncrementalKind, 25 IncrementalKind,
25 compile; 26 compile;
26 27
27 class Conversation { 28 class Conversation {
28 HttpRequest request; 29 HttpRequest request;
29 HttpResponse response; 30 HttpResponse response;
30 31
31 static const String PACKAGES_PATH = '/packages'; 32 static const String PACKAGES_PATH = '/packages';
32 33
33 static const String CONTENT_TYPE = HttpHeaders.CONTENT_TYPE; 34 static const String CONTENT_TYPE = HttpHeaders.CONTENT_TYPE;
34 35
35 static Uri documentRoot = Uri.base; 36 static Uri documentRoot = Uri.base;
36 37
37 static Uri packageRoot = Uri.base.resolve('packages/'); 38 static Uri packageRoot = Uri.base.resolve('packages/');
38 39
39 static Map<Uri, Future<String>> generatedFiles = 40 static Map<Uri, Future<String>> generatedFiles =
40 new Map<Uri, Future<String>>(); 41 new Map<Uri, Future<String>>();
41 42
43 static Map<Uri, StreamController<String>> updateControllers =
44 new Map<Uri, StreamController<String>>();
45
42 Conversation(this.request, this.response); 46 Conversation(this.request, this.response);
43 47
44 onClosed(_) { 48 onClosed(_) {
45 if (response.statusCode == HttpStatus.OK) return; 49 if (response.statusCode == HttpStatus.OK) return;
46 print('Request for ${request.uri} ${response.statusCode}'); 50 print('Request for ${request.uri} ${response.statusCode}');
47 } 51 }
48 52
49 Future notFound(Uri uri) { 53 Future notFound(Uri uri) {
50 response 54 response
51 ..headers.set(CONTENT_TYPE, 'text/html') 55 ..headers.set(CONTENT_TYPE, 'text/html')
52 ..statusCode = HttpStatus.NOT_FOUND 56 ..statusCode = HttpStatus.NOT_FOUND
53 ..write(htmlInfo("Not Found", "The file '$uri' could not be found.")); 57 ..write(htmlInfo("Not Found", "The file '$uri' could not be found."));
54 return response.close(); 58 return response.close();
55 } 59 }
56 60
57 Future badRequest(String problem) { 61 Future badRequest(String problem) {
58 response 62 response
59 ..headers.set(CONTENT_TYPE, 'text/html') 63 ..headers.set(CONTENT_TYPE, 'text/html')
60 ..statusCode = HttpStatus.BAD_REQUEST 64 ..statusCode = HttpStatus.BAD_REQUEST
61 ..write( 65 ..write(
62 htmlInfo("Bad request", "Bad request '${request.uri}': $problem")); 66 htmlInfo("Bad request", "Bad request '${request.uri}': $problem"));
63 return response.close(); 67 return response.close();
64 } 68 }
65 69
66 Future handleSocket() async { 70 Future handleSocket() async {
67 if (false && request.uri.path == '/ws/watch') { 71 StreamController<String> controller = updateControllers[request.uri];
72 if (controller != null) {
68 WebSocket socket = await WebSocketTransformer.upgrade(request); 73 WebSocket socket = await WebSocketTransformer.upgrade(request);
69 socket.add(JSON.encode({'create': []})); 74 print(
70 // WatchHandler handler = new WatchHandler(socket, files); 75 "Patches to ${request.uri} will be pushed to "
71 // handlers.add(handler); 76 "${request.connectionInfo.remoteAddress.host}:"
72 // socket.listen( 77 "${request.connectionInfo.remotePort}.");
73 // handler.onData, cancelOnError: true, onDone: handler.onDone); 78 controller.stream.pipe(socket);
74 } else { 79 } else {
75 response.done 80 response.done
76 .then(onClosed) 81 .then(onClosed)
77 .catchError(onError); 82 .catchError(onError);
78 return await notFound(request.uri); 83 return await notFound(request.uri);
79 } 84 }
80 } 85 }
81 86
82 Future handle() { 87 Future handle() {
83 response.done 88 response.done
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 if (path.endsWith('.html')) { 128 if (path.endsWith('.html')) {
124 response.headers.set(CONTENT_TYPE, 'text/html'); 129 response.headers.set(CONTENT_TYPE, 'text/html');
125 } else if (path.endsWith('.dart')) { 130 } else if (path.endsWith('.dart')) {
126 response.headers.set(CONTENT_TYPE, 'application/dart'); 131 response.headers.set(CONTENT_TYPE, 'application/dart');
127 } else if (path.endsWith('.js')) { 132 } else if (path.endsWith('.js')) {
128 response.headers.set(CONTENT_TYPE, 'application/javascript'); 133 response.headers.set(CONTENT_TYPE, 'application/javascript');
129 } else if (path.endsWith('.ico')) { 134 } else if (path.endsWith('.ico')) {
130 response.headers.set(CONTENT_TYPE, 'image/x-icon'); 135 response.headers.set(CONTENT_TYPE, 'image/x-icon');
131 } else if (path.endsWith('.appcache')) { 136 } else if (path.endsWith('.appcache')) {
132 response.headers.set(CONTENT_TYPE, 'text/cache-manifest'); 137 response.headers.set(CONTENT_TYPE, 'text/cache-manifest');
138 } else if (path.endsWith('.css')) {
139 response.headers.set(CONTENT_TYPE, 'text/css');
140 } else if (path.endsWith('.png')) {
141 response.headers.set(CONTENT_TYPE, 'image/png');
133 } 142 }
134 } 143 }
135 144
136 Future handleNonExistingFile(Uri uri) async { 145 Future handleNonExistingFile(Uri uri) async {
137 String path = uri.path; 146 String path = uri.path;
138 String generated = await generatedFiles[request.uri]; 147 String generated = await generatedFiles[request.uri];
139 if (generated != null) { 148 if (generated != null) {
140 print("Serving ${request.uri} from memory."); 149 print("Serving ${request.uri} from memory.");
141 setContentType(path); 150 setContentType(path);
142 response.write(generated); 151 response.write(generated);
143 return await response.close(); 152 return await response.close();
144 } 153 }
145 if (path.endsWith('.dart.js')) { 154 if (path.endsWith('.dart.js')) {
146 Uri dartScript = uri.resolve(path.substring(0, path.length - 3)); 155 Uri dartScript = uri.resolve(path.substring(0, path.length - 3));
147 if (await new File.fromUri(dartScript).exists()) { 156 if (await new File.fromUri(dartScript).exists()) {
148 return await compileToJavaScript(dartScript); 157 return await compileToJavaScript(dartScript);
149 } 158 }
150 } 159 }
151 return await notFound(request.uri); 160 return await notFound(request.uri);
152 } 161 }
153 162
154 compileToJavaScript(Uri dartScript) { 163 compileToJavaScript(Uri dartScript) {
155 Uri outputUri = request.uri; 164 Uri outputUri = request.uri;
156 Completer<String> completer = new Completer<String>(); 165 Completer<String> completer = new Completer<String>();
157 generatedFiles[outputUri] = completer.future; 166 generatedFiles[outputUri] = completer.future;
158 print("Compiling $dartScript to $outputUri"); 167 StreamController controller = updateControllers[outputUri];
168 if (controller != null) {
169 controller.close();
170 }
171 updateControllers[outputUri] = new StreamController<String>.broadcast();
172 print("Compiling $dartScript to $outputUri.");
159 StreamSubscription<CompilerEvent> subscription; 173 StreamSubscription<CompilerEvent> subscription;
160 subscription = compile(dartScript).listen((CompilerEvent event) { 174 subscription = compile(dartScript).listen((CompilerEvent event) {
161 subscription.onData( 175 subscription.onData(
162 (CompilerEvent event) => onCompilerEvent(completer, event)); 176 (CompilerEvent event) => onCompilerEvent(completer, event));
163 if (event.kind != IncrementalKind.FULL) { 177 if (event.kind != IncrementalKind.FULL) {
164 notFound(request.uri); 178 notFound(request.uri);
165 // TODO(ahe): Do something about this situation. 179 // TODO(ahe): Do something about this situation.
166 } else { 180 } else {
181 print("Done compiling $dartScript to $outputUri.");
167 completer.complete(event['.js']); 182 completer.complete(event['.js']);
168 setContentType(outputUri.path); 183 setContentType(outputUri.path);
169 response.write(event['.js']); 184 response.write(event['.js']);
170 response.close(); 185 response.close();
171 } 186 }
172 }); 187 });
173 } 188 }
174 189
175 onCompilerEvent(Completer completer, CompilerEvent event) { 190 onCompilerEvent(Completer completer, CompilerEvent event) {
176 Uri outputUri = request.uri; 191 Uri outputUri = request.uri;
177 print("Got ${event.kind} for $outputUri"); 192 print("Got ${event.kind} for $outputUri");
178 193
179 switch (event.kind) { 194 switch (event.kind) {
180 case IncrementalKind.FULL: 195 case IncrementalKind.FULL:
181 generatedFiles[outputUri] = new Future.value(event['.js']); 196 generatedFiles[outputUri] = new Future.value(event['.js']);
182 break; 197 break;
183 198
184 case IncrementalKind.INCREMENTAL: 199 case IncrementalKind.INCREMENTAL:
185 generatedFiles[outputUri] = completer.future.then( 200 generatedFiles[outputUri] = completer.future.then(
186 (String full) => '$full\n\n${event.compiler.allUpdates()}'); 201 (String full) => '$full\n\n${event.compiler.allUpdates()}');
202 pushUpdates(event.updates);
187 break; 203 break;
188 204
189 case IncrementalKind.ERROR: 205 case IncrementalKind.ERROR:
190 generatedFiles.removeKey(outputUri); 206 generatedFiles.removeKey(outputUri);
191 break; 207 break;
192 } 208 }
193 } 209 }
194 210
211 void pushUpdates(String updates) {
212 if (updates == null) return;
213 StreamController<String> controller = updateControllers[request.uri];
214 if (controller == null) return;
215 print("Adding updates to controller");
216 controller.add(updates);
217 }
218
195 Future dispatch() async { 219 Future dispatch() async {
196 try { 220 try {
197 return await WebSocketTransformer.isUpgradeRequest(request) 221 return await WebSocketTransformer.isUpgradeRequest(request)
198 ? handleSocket() 222 ? handleSocket()
199 : handle(); 223 : handle();
200 } catch (e, s) { 224 } catch (e, s) {
201 onError(e, s); 225 onError(e, s);
202 } 226 }
203 } 227 }
204 228
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 int port = options.port; 292 int port = options.port;
269 try { 293 try {
270 HttpServer server = await HttpServer.bind(host, port); 294 HttpServer server = await HttpServer.bind(host, port);
271 print('HTTP server started on http://$host:${server.port}/'); 295 print('HTTP server started on http://$host:${server.port}/');
272 server.listen(Conversation.onRequest, onError: Conversation.onStaticError); 296 server.listen(Conversation.onRequest, onError: Conversation.onStaticError);
273 } catch (e) { 297 } catch (e) {
274 print("HttpServer.bind error: $e"); 298 print("HttpServer.bind error: $e");
275 exit(1); 299 exit(1);
276 }; 300 };
277 } 301 }
OLDNEW
« no previous file with comments | « dart/pkg/dart2js_incremental/lib/dart2js_incremental.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698