platform/packages/production/README.md

139 lines
5.3 KiB
Markdown
Raw Normal View History

2021-07-18 05:36:33 +00:00
# Angel3 Production Runner
2021-12-19 02:07:55 +00:00
![Pub Version (including pre-releases)](https://img.shields.io/pub/v/angel3_production?include_prereleases)
2021-05-15 11:36:29 +00:00
[![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety)
2024-07-07 15:02:49 +00:00
[![Discord](https://img.shields.io/discord/1060322353214660698)](https://discord.gg/3X6bxTUdCM)
2023-12-25 03:45:10 +00:00
[![License](https://img.shields.io/github/license/dart-backend/belatuk-common-utilities)](https://github.com/dart-backend/angel/tree/master/packages/production/LICENSE)
2019-04-28 17:11:26 +00:00
2021-07-18 05:36:33 +00:00
Helpers for concurrency, message-passing, rotating loggers, and other production functionality in Angel3 framework.
2018-09-04 20:13:22 +00:00
2021-07-18 05:36:33 +00:00
![Screenshot](angel3-screenshot.png)
2018-09-04 20:16:01 +00:00
2023-11-13 00:59:18 +00:00
This will become the de-facto way to run Angel3 applications in deployed environments, as it takes care of inter-isolate communication, respawning dead processes, and other housekeeping for you automatically. Most users will want to use the `Runner` class.
2018-09-04 20:13:22 +00:00
## `Runner`
2021-07-18 05:36:33 +00:00
2018-09-04 20:13:22 +00:00
`Runner` is a utility, powered by `package:args`, that is intended to be the entry point of your application.
2021-07-18 05:36:33 +00:00
Instantiate it as follows, and your file will become a command-line executable that spawns multiple instances of your application:
2018-09-04 20:13:22 +00:00
```dart
import 'dart:async';
import 'dart:isolate';
2021-05-15 11:36:29 +00:00
import 'package:angel3_framework/angel3_framework.dart';
import 'package:angel3_production/angel3_production.dart';
2018-09-04 20:13:22 +00:00
2021-05-18 09:42:21 +00:00
void main(List<String> args) => Runner('example', configureServer).run(args);
2018-09-04 20:13:22 +00:00
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.
2019-04-28 17:51:08 +00:00
Timer(const Duration(seconds: 3), Isolate.current.kill);
2018-09-04 20:13:22 +00:00
return 'Crashing in 3s...';
});
}
```
2021-07-18 05:36:33 +00:00
`Runner` will automatically re-spawn crashed instances, unless `--no-respawn` is passed. This can prevent your server from entirely going down at the first error, and adds a layer of fault tolerance to your infrastructure.
2018-09-04 20:13:22 +00:00
2021-07-18 05:36:33 +00:00
When combined with `systemd`, deploying Angel3 applications on Linux can be very simple.
2018-09-04 20:13:22 +00:00
## Message Passing
2021-07-18 05:36:33 +00:00
2021-09-12 03:00:15 +00:00
The `Runner` class uses [`belatuk_pub_sub`](<https://pub.dev/packages/belatuk_pub_sub>) to coordinate
2023-11-13 00:59:18 +00:00
message passing between isolates. When one isolate sends a message, all other isolates will receive the same message, except for the isolate that sent it. It is injected into your application's `Container` as `pub_sub.Client`, so you can use it as follows:
2018-09-04 20:13:22 +00:00
```dart
2018-09-04 22:00:53 +00:00
// Use the injected `pub_sub.Client` to send messages.
2023-11-13 00:59:18 +00:00
var client = app.container.make<Client>();
2018-09-04 22:00:53 +00:00
// We can listen for an event to perform some behavior.
//
// Here, we use message passing to synchronize some common state.
var onGreetingChanged = await client.subscribe('user_upgraded');
onGreetingChanged
.cast<User>()
.listen((user) {
// Do something...
});
```
2023-11-13 00:59:18 +00:00
## Customising Response Header
Additional parameters can be passed to the `Runner` class to:
1. Remove headers from HTTP response.
2. Add headers to HTTP response.
2023-11-13 01:52:54 +00:00
For example, the following code snippet removes `X-FRAME-OPTIONS` and adds `X-XSRF-TOKEN` to the response header.
2023-11-13 00:59:18 +00:00
```dart
void main(List<String> args) {
2023-11-13 01:34:01 +00:00
// Remove 'X-FRAME-OPTIONS'
2023-11-13 00:59:18 +00:00
var removeHeader = {'X-FRAME-OPTIONS': 'SAMEORIGIN'};
2023-11-13 01:34:01 +00:00
2023-11-13 02:20:29 +00:00
// Add 'X-XSRF-TOKEN'
2023-11-13 00:59:18 +00:00
var customHeader = {
2023-11-13 01:34:01 +00:00
'X-XSRF-TOKEN':
2023-11-13 00:59:18 +00:00
'a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e'
};
Runner('example', configureServer,
removeResponseHeaders: removeHeader, responseHeaders: customHeader)
.run(args);
}
```
2018-09-04 22:00:53 +00:00
## Run-time Metadata
2021-07-18 05:36:33 +00:00
At run-time, you may want to know information about the currently-running instance, for example, which number instance. For this, the `InstanceInfo` class is injected into each instance:
2018-09-04 22:00:53 +00:00
```dart
var instanceInfo = app.container.make<InstanceInfo>();
print('This is instance #${instanceInfo.id}');
2018-09-04 20:16:01 +00:00
```
## Command-line Options
2021-07-18 05:36:33 +00:00
2018-09-04 20:16:01 +00:00
The `Runner` class supplies options like the following:
2021-07-18 05:36:33 +00:00
```bash
appuser$ dart example/main.dart --help
_ _ _ ____ _____ _ _____
/ \ | \ | |/ ___| ____| | |___ /
/ _ \ | \| | | _| _| | | |_ \
/ ___ \| |\ | |_| | |___| |___ ___) |
/_/ \_\_| \_|\____|_____|_____|____/
2018-09-04 20:16:01 +00:00
A batteries-included, full-featured, full-stack framework in Dart.
2021-07-18 05:36:33 +00:00
https://angel3-framework.web.app
2018-09-04 20:16:01 +00:00
Options:
2019-04-28 17:52:36 +00:00
-h, --help Print this help information.
--[no-]respawn Automatically respawn crashed application instances.
(defaults to on)
--use-zone Create a new Zone for each request.
--quiet Completely mute logging.
--ssl Listen for HTTPS instead of HTTP.
--http2 Listen for HTTP/2 instead of HTTP/1.1.
-a, --address The address to listen on.
(defaults to "127.0.0.1")
-j, --concurrency The number of isolates to spawn.
(defaults to "4")
-p, --port The port to listen on.
(defaults to "3000")
--certificate-file The PEM certificate file to read.
--certificate-password The PEM certificate file password.
--key-file The PEM key file to read.
--key-password The PEM key file password.
2021-07-18 05:36:33 +00:00
```