Add worker support to DDK

Change-Id: I0ae333f1bd6776840b1377579377695a582c46ef
Reviewed-on: https://dart-review.googlesource.com/30623
Reviewed-by: Jens Johansen <jensj@google.com>
Reviewed-by: Jake Macdonald <jakemac@google.com>
Commit-Queue: Sigmund Cherem <sigmund@google.com>
This commit is contained in:
Sigmund Cherem 2017-12-20 21:16:46 +00:00 committed by commit-bot@chromium.org
parent 548d7dc8a3
commit 22d3af523c

View file

@ -9,14 +9,18 @@ import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:bazel_worker/bazel_worker.dart';
import 'package:dev_compiler/src/kernel/command.dart';
import 'package:front_end/src/api_unstable/ddc.dart' as fe;
Future main(List<String> args) async {
if (args.isNotEmpty && args.last == "--batch") {
await runBatch(args.sublist(0, args.length - 1));
var parsedArgs = _preprocessArgs(args);
if (parsedArgs.isBatch) {
await runBatch(parsedArgs.args);
} else if (parsedArgs.isWorker) {
await new _CompilerWorker(parsedArgs.args).run();
} else {
var result = await compile(args);
var result = await compile(parsedArgs.args);
var succeeded = result.result;
exitCode = succeeded ? 0 : 1;
}
@ -60,3 +64,80 @@ Future runBatch(List<String> batchArgs) async {
var time = watch.elapsedMilliseconds;
print('>>> BATCH END (${tests - failed})/$tests ${time}ms');
}
/// Runs the compiler worker loop.
class _CompilerWorker extends AsyncWorkerLoop {
/// The original args supplied to the executable.
final List<String> _startupArgs;
_CompilerWorker(this._startupArgs) : super();
/// Performs each individual work request.
Future<WorkResponse> performRequest(WorkRequest request) async {
var args = _startupArgs.toList()..addAll(request.arguments);
var output = new StringBuffer();
var result = await runZoned(() => compile(args), zoneSpecification:
new ZoneSpecification(print: (self, parent, zone, message) {
output.writeln(message.toString());
}));
return new WorkResponse()
..exitCode = result.result ? 0 : 1
..output = output.toString();
}
}
/// Preprocess arguments to determine whether DDK is used in batch mode or as a
/// persistent worker.
///
/// When used in batch mode, we expect a `--batch` parameter last.
///
/// When used as a persistent bazel worker, the `--persistent_worker` might be
/// present, and an argument of the form `@path/to/file` might be provided. The
/// latter needs to be replaced by reading all the contents of the
/// file and expanding them into the resulting argument list.
_ParsedArgs _preprocessArgs(List<String> args) {
if (args.isEmpty) return new _ParsedArgs(false, false, args);
String lastArg = args.last;
if (lastArg == '--batch') {
return new _ParsedArgs(true, false, args.sublist(0, args.length - 1));
}
var newArgs = [];
bool isWorker = false;
var len = args.length;
for (int i = 0; i < len; i++) {
var arg = args[i];
if (i == len - 1 && arg.startsWith('@')) {
newArgs.addAll(_readLines(arg.substring(1)));
} else if (arg == '--persistent_worker') {
isWorker = true;
} else {
newArgs.add(arg);
}
}
return new _ParsedArgs(false, isWorker, newArgs);
}
/// Return all lines in a file found at [path].
Iterable<String> _readLines(String path) {
try {
return new File(path)
.readAsStringSync()
.replaceAll('\r\n', '\n')
.replaceAll('\r', '\n')
.split('\n')
.where((String line) => line.isNotEmpty);
} on FileSystemException catch (e) {
throw new Exception('Failed to read $path: $e');
}
}
class _ParsedArgs {
final bool isBatch;
final bool isWorker;
final List<String> args;
_ParsedArgs(this.isBatch, this.isWorker, this.args);
}