Application lifecycle
Learn the build, start, and close steps and the ownership of Lily-managed versus externally supplied resources.
WsAppBuilder defines application policies and components. WsApp owns their operation and shutdown. The listener, connections, and DI scopes belong to this lifecycle.
Build does not open a listener#
build().await reads the configuration snapshot, creates the DI container and controllers, runs new for registered workers, and validates route and policy plans. A successful return has not opened a listener yet. Errors such as repeated middleware, guards, or codecs in the same effective plan are caught before clients are admitted.
Builder → build → ready WsApp → start → accept connections and messages
↓ ↓
close sinyal / caller token / close / hata
└─────────── cleanup ve tamamlanma sonucuOn a failed or cancelled build, the framework retains rollback ownership of the resources it created. Independent tasks started by the user do not automatically enter this scope.
Start is called once#
start().await opens the listener and waits until the application shuts down. Registered workers run after listener bind and any Required backplane subscription are ready; readiness does not wait for the first job result. start_with_cancellation(token) connects a test's or enclosing application's shutdown signal. Platform signals remain active in this mode.
A WsApp cannot be restarted. If an application that has been started or closed needs another run, build a new app. WsApp does not provide public Clone; use Arc<WsApp> when management tasks need shared access.
Await the close result#
close().await also closes an app that has never been started. Concurrent and repeated calls observe the same stored shutdown result; calling again does not create a new time budget. Dropping the future awaiting start triggers shutdown; the cleanup owner does not disappear with that waiter.
A successful close means the required completion evidence has been collected. If it returns an error, account for the possibility that a resource is still in use. Requesting abort and verifying that a task has ended are different things. See shutdown for the detailed order.
External containers and tracing#
The entire container supplied through .container(Arc<ApplicationContainer>) remains yours. Lily closes the scopes it opens; it does not automatically close the external container. First successfully await app shutdown, then close the container's external owner. Do not unconditionally close the container when app shutdown fails.
.tracing_external() applies the same ownership distinction to telemetry. Lily starts, cancels, and awaits background services registered with add_background_service::<T>(). You must stop and await application tasks started with tokio::spawn yourself. The complete external-container and WSS example is explained on the transport page.
Sources for this page v0.1.0
This guide is based on the reviewed framework commit.