blob: 860487620e9138d09dc665d42a926654b987cd4e [file] [log] [blame]
library server.performance;
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:args/args.dart';
import 'package:logging/logging.dart';
import 'driver.dart';
import 'input_converter.dart';
import 'operation.dart';
/**
* Launch and interact with the analysis server.
*/
main(List<String> rawArgs) {
Logger logger = new Logger('Performance Measurement Client');
logger.onRecord.listen((LogRecord rec) {
print(rec.message);
});
Driver driver = new Driver(logger);
ArgResults args = parseArgs(rawArgs);
Stream<Operation> stream = openInput(args);
StreamSubscription<Operation> subscription;
subscription = stream.listen((Operation op) {
Future future = driver.perform(op);
if (future != null) {
logger.log(Level.FINE, 'pausing operations for ${op.runtimeType}');
subscription.pause(future.then((_) {
logger.log(Level.FINE, 'resuming operations');
}));
}
}, onDone: () {
subscription.cancel();
driver.stopServer();
}, onError: (e, s) {
subscription.cancel();
logger.log(Level.WARNING, '$e\n$s');
driver.stopServer();
throw e;
});
driver.runComplete.then((Results results) {
results.printResults();
}).whenComplete(() {
return subscription.cancel();
});
}
const HELP_CMDLINE_OPTION = 'help';
const INPUT_CMDLINE_OPTION = 'input';
const VERBOSE_CMDLINE_OPTION = 'verbose';
const VERY_VERBOSE_CMDLINE_OPTION = 'vv';
/**
* Open and return the input stream specifying how this client
* should interact with the analysis server.
*/
Stream<Operation> openInput(ArgResults args) {
Stream<List<int>> inputRaw;
String inputPath = args[INPUT_CMDLINE_OPTION];
if (inputPath == null) {
return null;
}
if (inputPath == 'stdin') {
inputRaw = stdin;
} else {
inputRaw = new File(inputPath).openRead();
}
return inputRaw
.transform(SYSTEM_ENCODING.decoder)
.transform(new LineSplitter())
.transform(new InputConverter());
}
/**
* Parse the command line arguments.
*/
ArgResults parseArgs(List<String> rawArgs) {
ArgParser parser = new ArgParser();
parser.addOption(INPUT_CMDLINE_OPTION,
abbr: 'i',
help: 'The input file specifying how this client should interact '
'with the server. If the input file name is "stdin", '
'then the instructions are read from standard input.');
parser.addFlag(VERBOSE_CMDLINE_OPTION,
abbr: 'v', help: 'Verbose logging', negatable: false);
parser.addFlag(VERY_VERBOSE_CMDLINE_OPTION,
help: 'Extra verbose logging', negatable: false);
parser.addFlag(HELP_CMDLINE_OPTION,
abbr: 'h', help: 'Print this help information', negatable: false);
ArgResults args = parser.parse(rawArgs);
bool showHelp = args[HELP_CMDLINE_OPTION] || args.rest.isNotEmpty;
if (args[INPUT_CMDLINE_OPTION] == null ||
args[INPUT_CMDLINE_OPTION].isEmpty) {
print('missing "input" argument');
showHelp = true;
}
if (args[VERY_VERBOSE_CMDLINE_OPTION] || rawArgs.contains('-vv')) {
Logger.root.level = Level.FINE;
} else if (args[VERBOSE_CMDLINE_OPTION]) {
Logger.root.level = Level.INFO;
} else {
Logger.root.level = Level.WARNING;
}
if (showHelp) {
print('');
print('Launch and interact with the AnalysisServer');
print(parser.usage);
exit(1);
}
return args;
}