Support SSL, HTTP2
This commit is contained in:
parent
d7e96ae616
commit
bbf16acaf5
10 changed files with 214 additions and 202230 deletions
|
@ -22,14 +22,14 @@ import 'dart:isolate';
|
|||
import 'package:angel_framework/angel_framework.dart';
|
||||
import 'package:angel_production/angel_production.dart';
|
||||
|
||||
main(List<String> args) => new Runner('example', configureServer).run(args);
|
||||
main(List<String> args) => Runner('example', configureServer).run(args);
|
||||
|
||||
Future configureServer(Angel app) async {
|
||||
app.get('/', (req, res) => 'Hello, production world!');
|
||||
|
||||
app.get('/crash', (req, res) {
|
||||
// We'll crash this instance deliberately, but the Runner will auto-respawn for us.
|
||||
new Timer(const Duration(seconds: 3), Isolate.current.kill);
|
||||
Timer(const Duration(seconds: 3), Isolate.current.kill);
|
||||
return 'Crashing in 3s...';
|
||||
});
|
||||
}
|
||||
|
|
29
dev.key
Normal file
29
dev.key
Normal file
|
@ -0,0 +1,29 @@
|
|||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIIE5DAcBgoqhkiG9w0BDAEBMA4ECL7L6rj6uEHGAgIIAASCBMLbucyfqAkgCbhP
|
||||
xNSHYllPMAv/dsIjtnsBwepCXPGkCBCuOAw/2FaCHjN9hBqL5V7fkrKeaemhm2YE
|
||||
ycPtlHJYPDf3kEkyMjdZ9rIY6kePGfQizs2uJPcXj4YPyQ4HsfVXpOicKfQrouf5
|
||||
Mze9bGzeMN065q3iP4dYUMwHAyZYteXCsanQNHlqvsWli0W+H8St8fdsXefZhnv1
|
||||
qVatKWdNdWQ9t5MuljgNU2Vv56sHKEYXI0yLxk2QUMk8KlJfnmt8foYUsnPUXHmc
|
||||
gIjLKwwVkpdololnEHSNu0cEOUPowjgJru+uMpn7vdNl7TPEQ9jbEgdNg4JwoYzU
|
||||
0nao8WzjaSp7kzvZz0VFwKnk5AjstGvvuAWckADdq23QElbn/mF7AG1m/TBpYxzF
|
||||
gTt37UdndS/AcvVznWVVrRP5iTSIawdIwvqI4s7rqsoE0GCcak+RhchgAz2gWKkS
|
||||
oODUo0JL6pPVbJ3l4ebbaO6c99nDVc8dViPtc1EkStJEJ2O4kI4xgLSCr4Y9ahKn
|
||||
oAaoSkX7Xxq3aQm+BzqSpLjdGL8atsqR/YVOIHYIl3gThvP0NfZGx1xHyvO5mCdZ
|
||||
kHxSA7tKWxauZ3eQ2clbnzeRsl4El0WMHy/5K1ovene4v7sunmoXVtghBC8hK6eh
|
||||
zMO9orex2PNQ/VQC7HCvtytunOVx1lkSBoNo7hR70igg6rW9H7UyoAoBOwMpT1xa
|
||||
J6V62nqruTKOqFNfur7aHJGpHGtDb5/ickHeYCyPTvmGp67u4wChzKReeg02oECe
|
||||
d1E5FKAcIa8s9TVOB6Z+HvTRNQZu2PsI6TJnjQRowvY9DAHiWTlJZBBY/pko3hxX
|
||||
TsIeybpvRdEHpDWv86/iqtw1hv9CUxS/8ZTWUgBo+osShHW79FeDASr9FC4/Zn76
|
||||
ZDERTgV4YWlW/klVWcG2lFo7jix+OPXAB+ZQavLhlN1xdWBcIz1AUWjAM4hdPylW
|
||||
HCX4PB9CQIPl2E7F+Y2p6nMcMWSJVBi5UIH7E9LfaBguXSzMmTk2Fw5p1aOQ6wfN
|
||||
goVAMVwi8ppAVs741PfHdZ295xMmK/1LCxz5DeAdD/tsA/SYfT753GotioDuC7im
|
||||
EyJ5JyvTr5I6RFFBuqt3NlUb3Hp16wP3B2x9DZiB6jxr0l341/NHgsyeBXkuIy9j
|
||||
ON2mvpBPCJhS8kgWo3G0UyyKnx64tcgpGuSvZhGwPz843B6AbYyE6pMRfSWRMkMS
|
||||
YZYa+VNKhR4ixdj07ocFZEWLVjCH7kxkE8JZXKt8jKYmkWd0lS1QVjgaKlO6lRa3
|
||||
q6SPJkhW6pvqobvcqVNXwi1XuzpZeEbuh0B7OTekFTTxx5g9XeDl56M8SVQ1KEhT
|
||||
Q1t7H2Nba18WCB7cf+6PN0F0K0Jz1Kq7ZWaqEI/grX1m4RQuvNF5807sB/QKMO/Z
|
||||
Gz3NXvHg5xTJRd/567lxPGkor0cE7qD1EZfmJ2HrBYXQ91bhgA7LToBuMZo6ZRXH
|
||||
QfsanjbP4FPLMiGdQigLjj3A35L/f4sQOOVac/sRaFnm7pzcxsMvyVU/YtvGcjYE
|
||||
xaOOVnamg661Wo0wksXoDjeSz/JIyyKO3Gwp1FSm2wGLjjy/Ehmqcqy8rvHuf07w
|
||||
AUukhVtTNn4=
|
||||
-----END ENCRYPTED PRIVATE KEY-----
|
57
dev.pem
Normal file
57
dev.pem
Normal file
|
@ -0,0 +1,57 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDKTCCAhGgAwIBAgIJAOWmjTS+OnTEMA0GCSqGSIb3DQEBCwUAMBcxFTATBgNV
|
||||
BAMMDGludGVybWVkaWF0ZTAeFw0xNTA1MTgwOTAwNDBaFw0yMzA4MDQwOTAwNDBa
|
||||
MBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
|
||||
AQoCggEBALlcwQJuzd+xH8QFgfJSn5tRlvhkldSX98cE7NiA602NBbnAVyUrkRXq
|
||||
Ni75lgt0kwjYfA9z674m8WSVbgpLPintPCla9CYky1TH0keIs8Rz6cGWHryWEHiu
|
||||
EDuljQynu2b3sAFuHu9nfWurbJwZnFakBKpdQ9m4EyOZCHC/jHYY7HacKSXg1Cki
|
||||
we2ca0BWDrcqy8kLy0dZ5oC6IZG8O8drAK8f3f44CRYw59D3sOKBrKXaabpvyEcb
|
||||
N7Wk2HDBVwHpUJo1reVwtbM8dhqQayYSD8oXnGpP3RQNu/e2rzlXRyq/BfcDY1JI
|
||||
7TbC4t/7/N4EcPSpGsTcSOC9A7FpzvECAwEAAaN7MHkwCQYDVR0TBAIwADAsBglg
|
||||
hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O
|
||||
BBYEFCnwiEMMFZh7NhCr+qA8K0w4Q+AOMB8GA1UdIwQYMBaAFB0h1Evsaw2vfrmS
|
||||
YuoCTmC4EE6ZMA0GCSqGSIb3DQEBCwUAA4IBAQAcFmHMaXRxyoNaeOowQ6iQWoZd
|
||||
AUbvG7SHr7I6Pi2aqdqofsKWts7Ytm5WsS0M2nN+sW504houu0iCPeJJX8RQw2q4
|
||||
CCcNOs9IXk+2uMzlpocHpv+yYoUiD5DxgWh7eghQMLyMpf8FX3Gy4VazeuXznHOM
|
||||
4gE4L417xkDzYOzqVTp0FTyAPUv6G2euhNCD6TMru9REcRhYul+K9kocjA5tt2KG
|
||||
MH6y28LXbLyq4YJUxSUU9gY/xlnbbZS48KDqEcdYC9zjW9nQ0qS+XQuQuFIcwjJ5
|
||||
V4kAUYxDu6FoTpyQjgsrmBbZlKNxH7Nj4NDlcdJhp/zeSKHqWa5hSWjjKIxp
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDAjCCAeqgAwIBAgIJAOWmjTS+OnTDMA0GCSqGSIb3DQEBCwUAMBgxFjAUBgNV
|
||||
BAMMDXJvb3RhdXRob3JpdHkwHhcNMTUwNTE4MDkwMDQwWhcNMjMwODA0MDkwMDQw
|
||||
WjAXMRUwEwYDVQQDDAxpbnRlcm1lZGlhdGUwggEiMA0GCSqGSIb3DQEBAQUAA4IB
|
||||
DwAwggEKAoIBAQDSrAO1CoPvUllgLOzDm5nG0skDF7vh1DUgAIDVGz0ecD0JFbQx
|
||||
EF79pju/6MbtpTW2FYvRp11t/G7rGtX923ybOHY/1MNFQrdIvPlO1VV7IGKjoMwP
|
||||
DNeb0fIGjHoE9QxaDxR8NX8xQbItpsw+TUtRfc9SLkR+jaYJfVRoM21BOncZbSHE
|
||||
YKiZlEbpecB/+EtwVpgvl+8mPD5U07Fi4fp/lza3WXInXQPyiTVllIEJCt4PKmlu
|
||||
MocNaJOW38bysL7i0PzDpVZtOxLHOTaW68yF3FckIHNCaA7k1ABEEEegjFMmIao7
|
||||
B9w7A0jvr4jZVvNmui5Djjn+oJxwEVVgyf8LAgMBAAGjUDBOMB0GA1UdDgQWBBQd
|
||||
IdRL7GsNr365kmLqAk5guBBOmTAfBgNVHSMEGDAWgBRk81s9d0ZbiZhh44KckwPb
|
||||
oTc0XzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBZQTK0plfdB5PC
|
||||
cC5icut4EmrByJa1RbU7ayuEE70e7hla6KVmVjVdCBGltI4jBYwfhKbRItHiAJ/8
|
||||
x+XZKBG8DLPFuDb7lAa1ObhAYF7YThUFPQYaBhfzKcWrdmWDBFpvNv6E0Mm364dZ
|
||||
e7Yxmbe5S4agkYPoxEzgEYmcUk9jbjdR6eTbs8laG169ljrECXfEU9RiAcqz5iSX
|
||||
NLSewqB47hn3B9qgKcQn+PsgO2j7M+rfklhNgeGJeWmy7j6clSOuCsIjWHU0RLQ4
|
||||
0W3SB/rpEAJ7fgQbYUPTIUNALSOWi/o1tDX2mXPRjBoxqAv7I+vYk1lZPmSzkyRh
|
||||
FKvRDxsW
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDAzCCAeugAwIBAgIJAJ0MomS4Ck+8MA0GCSqGSIb3DQEBCwUAMBgxFjAUBgNV
|
||||
BAMMDXJvb3RhdXRob3JpdHkwHhcNMTUwNTE4MDkwMDQwWhcNMjMwODA0MDkwMDQw
|
||||
WjAYMRYwFAYDVQQDDA1yb290YXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOC
|
||||
AQ8AMIIBCgKCAQEAts1ijtBV92S2cOvpUMOSTp9c6A34nIGr0T5Nhz6XiqRVT+gv
|
||||
dQgmkdKJQjbvR60y6jzltYFsI2MpGVXY8h/oAL81D/k7PDB2aREgyBfTPAhBHyGw
|
||||
siR+2xYt5b/Zs99q5RdRqQNzNpLPJriIKvUsRyQWy1UiG2s7pRXQeA8qB0XtJdCj
|
||||
kFIi+G2bDsaffspGeDOCqt7t+yqvRXfSES0c/l7DIHaiMbbp4//ZNML3RNgAjPz2
|
||||
hCezZ+wOYajOIyoSPK8IgICrhYFYxvgWxwbLDBEfC5B3jOQsySe10GoRAKZz1gBV
|
||||
DmgReu81tYJmdgkc9zknnQtIFdA0ex+GvZlfWQIDAQABo1AwTjAdBgNVHQ4EFgQU
|
||||
ZPNbPXdGW4mYYeOCnJMD26E3NF8wHwYDVR0jBBgwFoAUZPNbPXdGW4mYYeOCnJMD
|
||||
26E3NF8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEATzkZ97K777uZ
|
||||
lQcduNX3ey4IbCiEzFA2zO5Blj+ilfIwNbZXNOgm/lqNvVGDYs6J1apJJe30vL3X
|
||||
J+t2zsZWzzQzb9uIU37zYemt6m0fHrSrx/iy5lGNqt3HMfqEcOqSCOIK3PCTMz2/
|
||||
uyGe1iw33PVeWsm1JUybQ9IrU/huJjbgOHU4wab+8SJCM49ipArp68Fr6j4lcEaE
|
||||
4rfRg1ZsvxiOyUB3qPn6wyL/JB8kOJ+QCBe498376eaem8AEFk0kQRh6hDaWtq/k
|
||||
t6IIXQLjx+EBDVP/veK0UnVhKRP8YTOoV8ZiG1NcdlJmX/Uk7iAfevP7CkBfSN8W
|
||||
r6AL284qtw==
|
||||
-----END CERTIFICATE-----
|
|
@ -4,7 +4,7 @@ import 'package:angel_framework/angel_framework.dart';
|
|||
import 'package:angel_production/angel_production.dart';
|
||||
import 'package:pub_sub/pub_sub.dart' as pub_sub;
|
||||
|
||||
main(List<String> args) => new Runner('example', configureServer).run(args);
|
||||
main(List<String> args) => Runner('example', configureServer).run(args);
|
||||
|
||||
Future configureServer(Angel app) async {
|
||||
// Use the injected `pub_sub.Client` to send messages.
|
||||
|
@ -22,6 +22,11 @@ Future configureServer(Angel app) async {
|
|||
// Add some routes...
|
||||
app.get('/', (req, res) => 'Hello, production world!');
|
||||
|
||||
app.get('/404', (req, res) {
|
||||
res.statusCode = 404;
|
||||
return res.close();
|
||||
});
|
||||
|
||||
// Create some routes to demonstrate message passing.
|
||||
app.get('/greeting', (req, res) => greeting);
|
||||
|
||||
|
@ -35,7 +40,7 @@ Future configureServer(Angel app) async {
|
|||
// The `Runner` helps with fault tolerance.
|
||||
app.get('/crash', (req, res) {
|
||||
// We'll crash this instance deliberately, but the Runner will auto-respawn for us.
|
||||
new Timer(const Duration(seconds: 3), Isolate.current.kill);
|
||||
Timer(const Duration(seconds: 3), Isolate.current.kill);
|
||||
return 'Crashing in 3s...';
|
||||
});
|
||||
}
|
||||
|
|
183470
example/main.dill
183470
example/main.dill
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
18711
example/main.dill.txt
18711
example/main.dill.txt
File diff suppressed because one or more lines are too long
|
@ -2,7 +2,7 @@ import 'dart:io';
|
|||
import 'package:args/args.dart';
|
||||
|
||||
class RunnerOptions {
|
||||
static final ArgParser argParser = new ArgParser()
|
||||
static final ArgParser argParser = ArgParser()
|
||||
..addFlag('help',
|
||||
abbr: 'h', help: 'Print this help information.', negatable: false)
|
||||
..addFlag('respawn',
|
||||
|
@ -11,6 +11,11 @@ class RunnerOptions {
|
|||
negatable: true)
|
||||
..addFlag('use-zone',
|
||||
negatable: false, help: 'Create a new Zone for each request.')
|
||||
..addFlag('quiet', negatable: false, help: 'Completely mute logging.')
|
||||
..addFlag('ssl',
|
||||
negatable: false, help: 'Listen for HTTPS instead of HTTP.')
|
||||
..addFlag('http2',
|
||||
negatable: false, help: 'Listen for HTTP/2 instead of HTTP/1.1.')
|
||||
..addOption('address',
|
||||
abbr: 'a', defaultsTo: '127.0.0.1', help: 'The address to listen on.')
|
||||
..addOption('concurrency',
|
||||
|
@ -18,26 +23,57 @@ class RunnerOptions {
|
|||
defaultsTo: Platform.numberOfProcessors.toString(),
|
||||
help: 'The number of isolates to spawn.')
|
||||
..addOption('port',
|
||||
abbr: 'p', defaultsTo: '3000', help: 'The port to listen on.');
|
||||
abbr: 'p', defaultsTo: '3000', help: 'The port to listen on.')
|
||||
..addOption('certificate-file', help: 'The PEM certificate file to read.')
|
||||
..addOption('certificate-password',
|
||||
help: 'The PEM certificate file password.')
|
||||
..addOption('key-file', help: 'The PEM key file to read.')
|
||||
..addOption('key-password', help: 'The PEM key file password.');
|
||||
|
||||
final String hostname;
|
||||
final String hostname,
|
||||
certificateFile,
|
||||
keyFile,
|
||||
certificatePassword,
|
||||
keyPassword;
|
||||
final int concurrency, port;
|
||||
final bool useZone, respawn;
|
||||
final bool useZone, respawn, quiet, ssl, http2;
|
||||
|
||||
RunnerOptions(
|
||||
{this.hostname = '127.0.0.1',
|
||||
this.port = 3000,
|
||||
this.concurrency = 1,
|
||||
this.useZone = false,
|
||||
this.respawn = true});
|
||||
this.respawn = true,
|
||||
this.quiet = false,
|
||||
this.certificateFile,
|
||||
this.keyFile,
|
||||
this.ssl = false,
|
||||
this.http2 = false,
|
||||
this.certificatePassword,
|
||||
this.keyPassword});
|
||||
|
||||
factory RunnerOptions.fromArgResults(ArgResults argResults) {
|
||||
return new RunnerOptions(
|
||||
return RunnerOptions(
|
||||
hostname: argResults['address'] as String,
|
||||
port: int.parse(argResults['port'] as String),
|
||||
concurrency: int.parse(argResults['concurrency'] as String),
|
||||
useZone: argResults['use-zone'] as bool,
|
||||
respawn: argResults['respawn'] as bool,
|
||||
quiet: argResults['quiet'] as bool,
|
||||
certificateFile: argResults.wasParsed('certificate-file')
|
||||
? argResults['certificate-file'] as String
|
||||
: null,
|
||||
keyFile: argResults.wasParsed('key-file')
|
||||
? argResults['key-file'] as String
|
||||
: null,
|
||||
ssl: argResults['ssl'] as bool,
|
||||
http2: argResults['http2'] as bool,
|
||||
certificatePassword: argResults.wasParsed('certificate-password')
|
||||
? argResults['certificate-password'] as String
|
||||
: null,
|
||||
keyPassword: argResults.wasParsed('key-password')
|
||||
? argResults['key-password'] as String
|
||||
: null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import 'dart:isolate';
|
|||
import 'package:angel_container/angel_container.dart';
|
||||
import 'package:angel_framework/angel_framework.dart';
|
||||
import 'package:angel_framework/http.dart';
|
||||
import 'package:angel_framework/http2.dart';
|
||||
import 'package:args/args.dart';
|
||||
import 'package:io/ansi.dart';
|
||||
import 'package:io/io.dart';
|
||||
|
@ -73,17 +74,17 @@ _ ___ | /| / / /_/ / _ /___ _ /___
|
|||
///
|
||||
/// If respawning is enabled, the [Future] will *never* complete.
|
||||
Future spawnIsolate(int id, RunnerOptions options, SendPort pubSubSendPort) {
|
||||
return _spawnIsolate(id, new Completer(), options, pubSubSendPort);
|
||||
return _spawnIsolate(id, Completer(), options, pubSubSendPort);
|
||||
}
|
||||
|
||||
Future _spawnIsolate(
|
||||
int id, Completer c, RunnerOptions options, SendPort pubSubSendPort) {
|
||||
var onLogRecord = new ReceivePort();
|
||||
var onExit = new ReceivePort();
|
||||
var onError = new ReceivePort();
|
||||
var runnerArgs = new _RunnerArgs(name, configureServer, options, reflector,
|
||||
var onLogRecord = ReceivePort();
|
||||
var onExit = ReceivePort();
|
||||
var onError = ReceivePort();
|
||||
var runnerArgs = _RunnerArgs(name, configureServer, options, reflector,
|
||||
onLogRecord.sendPort, pubSubSendPort);
|
||||
var argsWithId = new _RunnerArgsWithId(id, runnerArgs);
|
||||
var argsWithId = _RunnerArgsWithId(id, runnerArgs);
|
||||
|
||||
Isolate.spawn(isolateMain, argsWithId,
|
||||
onExit: onExit.sendPort,
|
||||
|
@ -97,19 +98,19 @@ _ ___ | /| / / /_/ / _ /___ _ /___
|
|||
onError.listen((msg) {
|
||||
if (msg is List) {
|
||||
var e = msg[0], st = StackTrace.fromString(msg[1].toString());
|
||||
handleLogRecord(new LogRecord(
|
||||
handleLogRecord(LogRecord(
|
||||
Level.SEVERE, 'Fatal error', runnerArgs.loggerName, e, st));
|
||||
} else {
|
||||
handleLogRecord(new LogRecord(
|
||||
Level.SEVERE, 'Fatal error', runnerArgs.loggerName, msg));
|
||||
handleLogRecord(
|
||||
LogRecord(Level.SEVERE, 'Fatal error', runnerArgs.loggerName, msg));
|
||||
}
|
||||
});
|
||||
|
||||
onExit.listen((_) {
|
||||
if (options.respawn) {
|
||||
handleLogRecord(new LogRecord(
|
||||
handleLogRecord(LogRecord(
|
||||
Level.WARNING,
|
||||
'Instance #$id at ${new DateTime.now()}. Respawning immediately...',
|
||||
'Instance #$id at ${DateTime.now()} crashed. Respawning immediately...',
|
||||
runnerArgs.loggerName));
|
||||
_spawnIsolate(id, c, options, pubSubSendPort);
|
||||
} else {
|
||||
|
@ -129,7 +130,15 @@ _ ___ | /| / / /_/ / _ /___ _ /___
|
|||
|
||||
try {
|
||||
var argResults = RunnerOptions.argParser.parse(args);
|
||||
var options = new RunnerOptions.fromArgResults(argResults);
|
||||
var options = RunnerOptions.fromArgResults(argResults);
|
||||
|
||||
if (options.ssl || options.http2) {
|
||||
if (options.certificateFile == null) {
|
||||
throw ArgParserException('Missing --certificate-file option.');
|
||||
} else if (options.keyFile == null) {
|
||||
throw ArgParserException('Missing --key-file option.');
|
||||
}
|
||||
}
|
||||
|
||||
print(darkGray.wrap(asciiArt.trim() +
|
||||
'\n\n' +
|
||||
|
@ -143,29 +152,30 @@ _ ___ | /| / / /_/ / _ /___ _ /___
|
|||
}
|
||||
|
||||
print('Starting `${name}` application...');
|
||||
print('Arguments: $args...\n');
|
||||
|
||||
var adapter = new pub_sub.IsolateAdapter();
|
||||
server = new pub_sub.Server([adapter]);
|
||||
var adapter = pub_sub.IsolateAdapter();
|
||||
server = pub_sub.Server([adapter]);
|
||||
|
||||
// Register clients
|
||||
for (int i = 0; i < Platform.numberOfProcessors; i++) {
|
||||
server.registerClient(new pub_sub.ClientInfo('client$i'));
|
||||
server.registerClient(pub_sub.ClientInfo('client$i'));
|
||||
}
|
||||
|
||||
server.start();
|
||||
|
||||
await Future.wait(new List.generate(options.concurrency,
|
||||
await Future.wait(List.generate(options.concurrency,
|
||||
(id) => spawnIsolate(id, options, adapter.receivePort.sendPort)));
|
||||
} on ArgParserException catch (e) {
|
||||
stderr
|
||||
..writeln(e.message)
|
||||
..writeln(red.wrap(e.message))
|
||||
..writeln()
|
||||
..writeln('Options:')
|
||||
..writeln(RunnerOptions.argParser.usage);
|
||||
..writeln(red.wrap('Options:'))
|
||||
..writeln(red.wrap(RunnerOptions.argParser.usage));
|
||||
exitCode = ExitCode.usage.code;
|
||||
} catch (e) {
|
||||
stderr..writeln('fatal error: $e');
|
||||
} catch (e, st) {
|
||||
stderr
|
||||
..writeln(red.wrap('fatal error: $e'))
|
||||
..writeln(red.wrap(st.toString()));
|
||||
exitCode = 1;
|
||||
} finally {
|
||||
await server?.close();
|
||||
|
@ -176,37 +186,66 @@ _ ___ | /| / / /_/ / _ /___ _ /___
|
|||
var args = argsWithId.args;
|
||||
hierarchicalLoggingEnabled = true;
|
||||
|
||||
var zone = Zone.current.fork(specification: new ZoneSpecification(
|
||||
var zone = Zone.current.fork(specification: ZoneSpecification(
|
||||
print: (self, parent, zone, msg) {
|
||||
args.loggingSendPort
|
||||
.send(new LogRecord(Level.INFO, msg, args.loggerName));
|
||||
args.loggingSendPort.send(LogRecord(Level.INFO, msg, args.loggerName));
|
||||
},
|
||||
));
|
||||
|
||||
zone.run(() async {
|
||||
var client = new pub_sub.IsolateClient(
|
||||
'client${argsWithId.id}', args.pubSubSendPort);
|
||||
var client =
|
||||
pub_sub.IsolateClient('client${argsWithId.id}', args.pubSubSendPort);
|
||||
|
||||
var app = new Angel(reflector: args.reflector)
|
||||
var app = Angel(reflector: args.reflector)
|
||||
..container.registerSingleton<pub_sub.Client>(client)
|
||||
..container.registerSingleton(new InstanceInfo(id: argsWithId.id));
|
||||
..container.registerSingleton(InstanceInfo(id: argsWithId.id));
|
||||
|
||||
app.shutdownHooks.add((_) => client.close());
|
||||
|
||||
await app.configure(args.configureServer);
|
||||
|
||||
if (app.logger == null) {
|
||||
app.logger = new Logger(args.loggerName)
|
||||
app.logger = Logger(args.loggerName)
|
||||
..onRecord.listen(Runner.handleLogRecord);
|
||||
}
|
||||
|
||||
var http =
|
||||
new AngelHttp.custom(app, startShared, useZone: args.options.useZone);
|
||||
var server =
|
||||
await http.startServer(args.options.hostname, args.options.port);
|
||||
var url = new Uri(
|
||||
scheme: 'http', host: server.address.address, port: server.port);
|
||||
print('Instance #${argsWithId.id} listening at $url');
|
||||
AngelHttp http;
|
||||
SecurityContext securityContext;
|
||||
Uri serverUrl;
|
||||
|
||||
if (args.options.ssl || args.options.http2) {
|
||||
securityContext = SecurityContext();
|
||||
securityContext.useCertificateChain(args.options.certificateFile,
|
||||
password: args.options.certificatePassword);
|
||||
securityContext.usePrivateKey(args.options.keyFile,
|
||||
password: args.options.keyPassword);
|
||||
}
|
||||
|
||||
if (args.options.ssl) {
|
||||
http = AngelHttp.custom(app, startSharedSecure(securityContext),
|
||||
useZone: args.options.useZone);
|
||||
} else {
|
||||
http =
|
||||
AngelHttp.custom(app, startShared, useZone: args.options.useZone);
|
||||
}
|
||||
|
||||
Driver driver;
|
||||
|
||||
if (args.options.http2) {
|
||||
securityContext.setAlpnProtocols(['h2'], true);
|
||||
var http2 = AngelHttp2.custom(app, securityContext, startSharedHttp2,
|
||||
useZone: args.options.useZone);
|
||||
http2.onHttp1.listen(http.handleRequest);
|
||||
driver = http2;
|
||||
} else {
|
||||
driver = http;
|
||||
}
|
||||
|
||||
await driver.startServer(args.options.hostname, args.options.port);
|
||||
serverUrl = driver.uri;
|
||||
if (args.options.ssl || args.options.http2)
|
||||
serverUrl = serverUrl.replace(scheme: 'https');
|
||||
print('Instance #${argsWithId.id} listening at $serverUrl');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,4 +13,4 @@ dependencies:
|
|||
logging: ^0.11.3
|
||||
pub_sub: ^2.0.0
|
||||
dev_dependencies:
|
||||
pedantic: ^1.0.0
|
||||
pedantic: ^1.0.0
|
Loading…
Reference in a new issue