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

Side by Side Diff: lib/src/runner/browser/compiler_pool.dart

Issue 1196413003: Add a LoadSuite class. (Closed) Base URL: git@github.com:dart-lang/test@master
Patch Set: Created 5 years, 6 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
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 test.util.compiler_pool; 5 library test.util.compiler_pool;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:convert';
9 import 'dart:io'; 9 import 'dart:io';
10 10
11 import 'package:path/path.dart' as p; 11 import 'package:path/path.dart' as p;
12 import 'package:pool/pool.dart'; 12 import 'package:pool/pool.dart';
13 13
14 import '../../util/async_thunk.dart'; 14 import '../../util/async_thunk.dart';
15 import '../../util/io.dart'; 15 import '../../util/io.dart';
16 import '../../utils.dart';
17 import '../load_exception.dart'; 16 import '../load_exception.dart';
18 17
19 /// A pool of `dart2js` instances. 18 /// A pool of `dart2js` instances.
20 /// 19 ///
21 /// This limits the number of compiler instances running concurrently. It also 20 /// This limits the number of compiler instances running concurrently.
22 /// ensures that their output doesn't intermingle; only one instance is
23 /// "visible" (that is, having its output printed) at a time, and the other
24 /// instances' output is buffered until it's their turn to be visible.
25 class CompilerPool { 21 class CompilerPool {
26 /// The internal pool that controls the number of process running at once. 22 /// The internal pool that controls the number of process running at once.
27 final Pool _pool; 23 final Pool _pool;
28 24
29 /// Whether to enable colors on dart2js. 25 /// Whether to enable colors on dart2js.
30 final bool _color; 26 final bool _color;
31 27
32 /// The currently-active compilers. 28 /// The currently-active dart2js processes.
33 /// 29 final _processes = new Set<Process>();
34 /// The first one is the only visible the compiler; the rest will become
35 /// visible in queue order. Note that some of these processes may actually
36 /// have already exited; they're kept around so that their output can be
37 /// emitted once they become visible.
38 final _compilers = new Queue<_Compiler>();
39 30
40 /// Whether [close] has been called. 31 /// Whether [close] has been called.
41 bool get _closed => _closeThunk.hasRun; 32 bool get _closed => _closeThunk.hasRun;
42 33
43 /// The thunk for running [close] exactly once. 34 /// The thunk for running [close] exactly once.
44 final _closeThunk = new AsyncThunk(); 35 final _closeThunk = new AsyncThunk();
45 36
46 /// Creates a compiler pool that runs up to [concurrency] instances of 37 /// Creates a compiler pool that runs up to [concurrency] instances of
47 /// `dart2js` at once. 38 /// `dart2js` at once.
48 /// 39 ///
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 73
83 var args = ["--checked", wrapperPath, "--out=$jsPath", "--show-package-w arnings"]; 74 var args = ["--checked", wrapperPath, "--out=$jsPath", "--show-package-w arnings"];
84 75
85 if (packageRoot != null) { 76 if (packageRoot != null) {
86 args.add("--package-root=${p.toUri(p.absolute(packageRoot))}"); 77 args.add("--package-root=${p.toUri(p.absolute(packageRoot))}");
87 } 78 }
88 79
89 if (_color) args.add("--enable-diagnostic-colors"); 80 if (_color) args.add("--enable-diagnostic-colors");
90 81
91 var process = await Process.start(dart2jsPath, args); 82 var process = await Process.start(dart2jsPath, args);
92 var compiler = new _Compiler(dartPath, process); 83 if (_closed) {
84 process.kill();
85 return;
86 }
93 87
94 if (_compilers.isEmpty) _showProcess(compiler); 88 _processes.add(process);
95 _compilers.add(compiler);
96 89
97 await compiler.onDone; 90 /// Wait until the process is entirely done to print out any output.
91 /// This can produce a little extra time for users to wait with no
92 /// update, but it also avoids some really nasty-looking interleaved
93 /// output. Write both stdout and stderr to the same buffer in case
94 /// they're intended to be printed in order.
95 var buffer = new StringBuffer();
96
97 await Future.wait([
98 _printOutputStream(process.stdout, buffer),
99 _printOutputStream(process.stderr, buffer),
100 ]);
101
102 var exitCode = await process.exitCode;
103 _processes.remove(process);
104 if (_closed) return;
105
106 if (buffer.isNotEmpty) print(buffer);
107
108 if (exitCode != 0) {
109 throw new LoadException(dartPath, "dart2js failed.");
110 }
98 }); 111 });
99 }); 112 });
100 } 113 }
101 114
102 /// Mark [compiler] as the visible instance. 115 /// Sanitizes the bytes emitted by [stream], converts them to text, and writes
103 /// 116 /// them to [buffer].
104 /// This prints all [compiler]'s standard output and error. 117 Future _printOutputStream(Stream<List<int>> stream, StringBuffer buffer) {
105 void _showProcess(_Compiler compiler) { 118 return sanitizeForWindows(stream)
106 print("Compiling ${compiler.path}..."); 119 .listen((data) => buffer.write(UTF8.decode(data))).asFuture();
107
108 invoke(() async {
109 try {
110 // We wait for stdout and stderr to close and for exitCode to fire to
111 // ensure that we're done printing everything about one process before
112 // we start the next.
113 await Future.wait([
114 sanitizeForWindows(compiler.process.stdout).listen(stdout.add)
115 .asFuture(),
116 sanitizeForWindows(compiler.process.stderr).listen(stderr.add)
117 .asFuture(),
118 compiler.process.exitCode.then((exitCode) {
119 if (exitCode == 0 || _closed) return;
120 throw new LoadException(compiler.path, "dart2js failed.");
121 })
122 ]);
123
124 if (_closed) return;
125 compiler.onDoneCompleter.complete();
126 } catch (error, stackTrace) {
127 if (_closed) return;
128 compiler.onDoneCompleter.completeError(error, stackTrace);
129 }
130
131 _compilers.removeFirst();
132 if (_compilers.isEmpty) return;
133
134 var next = _compilers.first;
135
136 // Wait a bit before printing the next process in case the current one
137 // threw an error that needs to be printed.
138 Timer.run(() => _showProcess(next));
139 });
140 } 120 }
141 121
142 /// Closes the compiler pool. 122 /// Closes the compiler pool.
143 /// 123 ///
144 /// This kills all currently-running compilers and ensures that no more will 124 /// This kills all currently-running compilers and ensures that no more will
145 /// be started. It returns a [Future] that completes once all the compilers 125 /// be started. It returns a [Future] that completes once all the compilers
146 /// have been killed and all resources released. 126 /// have been killed and all resources released.
147 Future close() { 127 Future close() {
148 return _closeThunk.run(() async { 128 return _closeThunk.run(() async {
149 await Future.wait(_compilers.map((compiler) async { 129 await Future.wait(_processes.map((process) async {
150 compiler.process.kill(); 130 process.kill();
151 await compiler.process.exitCode; 131 await process.exitCode;
152 compiler.onDoneCompleter.complete();
153 })); 132 }));
154
155 _compilers.clear();
156 }); 133 });
157 } 134 }
158 } 135 }
159
160 /// A running instance of `dart2js`.
161 class _Compiler {
162 /// The path of the Dart file being compiled.
163 final String path;
164
165 /// The underlying process.
166 final Process process;
167
168 /// A future that will complete once this instance has finished running and
169 /// all its output has been printed.
170 Future get onDone => onDoneCompleter.future;
171 final onDoneCompleter = new Completer();
172
173 _Compiler(this.path, this.process);
174 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698