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:tuple/tuple.dart'; Future _runWrk( {ProcessStartMode mode = ProcessStartMode.inheritStdio}) async { return await Process.start('wrk', ['http://localhost:$testPort'], mode: mode); } Future _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 runBenchmarks(Iterable benchmarks, {Iterable 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 = []; // 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 = []; for (var 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 args) { Future(() async { var app = Angel(); late 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 setupAngel(Angel app); FutureOr rawHandler(HttpRequest req, HttpResponse res); }