puter/packages/backend/doc/contributors/boot-sequence.md
KernelDeimos 15dec21118 doc(backend): Document the boot sequence
Now that the boot sequence is better formalized it may be documented.
2024-05-13 16:00:07 -04:00

2.8 KiB

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.