platform/benchmark/util.dart
2019-05-01 00:29:21 -04:00

110 lines
3.2 KiB
Dart

import 'dart:async';
import 'dart:io';
import 'dart:isolate';
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_framework/http.dart';
import 'package:angel_wings/angel_wings.dart';
import 'package:io/ansi.dart';
import 'package:pedantic/pedantic.dart';
import 'package:tuple/tuple.dart';
Future<Process> _runWrk(
{ProcessStartMode mode = ProcessStartMode.inheritStdio}) async {
return await Process.start('wrk', ['http://localhost:$testPort'], mode: mode);
}
Future<void> _warmUp() async {
var wrk = await _runWrk();
await wrk.exitCode;
// await wrk.stderr.drain();
// await wrk.stdout.drain();
}
Future _10s() => Future.delayed(Duration(seconds: 10));
const testPort = 8877;
Future<void> runBenchmarks(Iterable<AngelBenchmark> benchmarks,
{Iterable<String> factories = const [
// 'angel_http',
'angel_wings',
]}) async {
for (var benchmark in benchmarks) {
print(magenta.wrap('Entering benchmark: ${benchmark.name}'));
// // Run dart:io
// print(lightGray.wrap('Booting dart:io server (waiting 10s)...'));
// var isolates = <Isolate>[];
// for (int i = 0; i < Platform.numberOfProcessors; i++) {
// isolates.add(await Isolate.spawn(_httpIsolate, benchmark));
// }
// await _10s();
// print(lightGray.wrap('Warming up dart:io server...'));
// await _warmUp();
// stdout
// ..write(lightGray.wrap('Now running `wrk` for '))
// ..write(cyan.wrap(benchmark.name))
// ..writeln(lightGray.wrap(' (waiting 10s)...'));
// var wrk = await _runWrk(mode: ProcessStartMode.inheritStdio);
// await wrk.exitCode;
// isolates.forEach((i) => i.kill(priority: Isolate.immediate));
// Run Angel HTTP, Wings
for (var fac in factories) {
print(lightGray.wrap('Booting $fac server...'));
var isolates = <Isolate>[];
for (int i = 0; i < Platform.numberOfProcessors; i++) {
isolates
.add(await Isolate.spawn(_angelIsolate, Tuple2(benchmark, fac)));
}
await _10s();
print(lightGray.wrap('Warming up $fac server...'));
await _warmUp();
stdout
..write(lightGray.wrap('Now running `wrk` for '))
..write(cyan.wrap(benchmark.name))
..writeln(lightGray.wrap('...'));
var wrk = await _runWrk(mode: ProcessStartMode.inheritStdio);
await wrk.exitCode;
}
}
exit(0);
}
void _httpIsolate(AngelBenchmark benchmark) {
Future(() async {
var raw = await HttpServer.bind(InternetAddress.loopbackIPv4, testPort,
shared: true);
raw.listen((r) => benchmark.rawHandler(r, r.response));
});
}
void _angelIsolate(Tuple2<AngelBenchmark, String> args) {
Future(() async {
var app = Angel();
Driver driver;
if (args.item2 == 'angel_http')
driver = AngelHttp.custom(app, startShared);
else if (args.item2 == 'angel_wings')
driver = AngelWings.custom(app, startSharedWings);
await app.configure(args.item1.setupAngel);
await driver.startServer(InternetAddress.loopbackIPv4, testPort);
});
}
abstract class AngelBenchmark {
const AngelBenchmark();
String get name;
FutureOr<void> setupAngel(Angel app);
FutureOr<void> rawHandler(HttpRequest req, HttpResponse res);
}