doc(backend): Document the boot sequence

Now that the boot sequence is better formalized it may be documented.
This commit is contained in:
KernelDeimos 2024-05-09 17:06:40 -04:00
parent d800b12569
commit 15dec21118

View File

@ -0,0 +1,87 @@
# Puter Backend Boot Sequence
This document describes the boot sequence of Puter's backend.
**Constriction**
- Data structures are created
**Initialization**
- Registries are populated
- Services prepare for next phase
**Consolidation**
- Service event bus receives first event (`boot.consolidation`)
- Services perform coordinated setup behaviors
- Services prepare for next phase
**Activation**
- Blocking listeners of `boot.consolidation` have resolved
- HTTP servers start listening
**Ready**
- Services are informed that Puter is providing service
## Boot Phases
### Construction
Services implement a method called `construct` which initializes members
of an instance. Services do not override the class constructor of
**BaseService**. This makes it possible to use the `new` operator without
invoking a service's constructor behavior during debugging.
The first phase of the boot sequence, "construction", is simply a loop to
call `construct` on all registered services.
The `_construct` override should not:
- call other services
- emit events
### Initialization
At initialization, the `init()` method is called on all services.
The `_init` override can be used to:
- register information with other services, when services don't
need to register this information in a specific sequence.
An example of this is registering commands with CommandService.
- perform setup that is required before the consolidation phase starts.
### Consolidation
Consolidation is a phase where services should emit events that
are related to bringing up the system. For example, WebServerService
('web-server') emits an event telling services to install middlewares,
and later emits an event telling services to install routes.
Consolidation starts when Kernel emits `boot.consolidation` to the
services event bus, which happens after `init()` resolves for all
services.
### Activation
Activation is a phase where services begin listening on external
interfaces. For example, this is when the web server starts listening.
Activation starts when Kernel emits `boot.activation`.
### Ready
Ready is a phase where services are informed that everything is up.
Ready starts when Kernel emits `boot.ready`.
## Events and Asynchronous Execution
The services event bus is implemented so you can `await` a call to `.emit()`.
Event listeners can choose to have blocking behavior by returning a promise.
During emission of a particular event, listeners of this event will not
block each other, but all listeners must resolve before the call to
`.emit()` is resolved. (i.e. `emit` uses `Promise.all`)
## Legacy Services
Some services were implemented before the `BaseService` class - which
implements the `init` method - was created. These services are called
"legacy services" and they are instantiated _after_ initialization but
_before_ consolidation.