From 2d05e6fb933d8c33078232b3bdfbc2aa05106d80 Mon Sep 17 00:00:00 2001 From: Owen Jacobson Date: Mon, 27 Oct 2025 17:07:53 -0400 Subject: Make `Boot` a freestanding app type, rather than a view of `crate::app::App`'s internals. In the course of working on web push, I determined that we probably need to make `App` generic over the web push client we're using, so that tests can use a dummy client while the real app uses a client created at startup and maintained over the life of the program's execution. The most direct implementation of that is to render App as `App

`, where the parameter is occupied by the specific web push client type in use. However, doing this requires refactoring at _every_ site that mentions `App`, including every handler, even though the vast majority of those sites will not be concerned with web push. I reviewed a few options with @wlonk: * Accept the type parameter and apply it everywhere, as the cost of supporting web push. * Hard-code the use of a specific web push client. * Insulate handlers &c from `App` via provider traits, mimicing what we do for repository provider traits today. * Treat each app type as a freestanding state in its own right, so that only push-related components need to consider push clients (as far as is feasible). This is a prototype towards that last point, using a simple app component (boot) as a testbed. `FromRef` allows handlers that take a `Boot` to be used in routes that provide an `App`, so this is a contained change. However, the structure of `FromRef` prevents `Boot` from carrying any lifetime narrower than `'static`, so it now holds clones of the state fields it acquires from App, instead of references. This is fine - that's just a database pool, and sqlx's pool type is designed to be shared via cloning. From : > Cloning Pool is cheap as it is simply a reference-counted handle to the inner pool state. --- src/test/fixtures/boot.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/test/fixtures/boot.rs') diff --git a/src/test/fixtures/boot.rs b/src/test/fixtures/boot.rs index 120726f..7421512 100644 --- a/src/test/fixtures/boot.rs +++ b/src/test/fixtures/boot.rs @@ -1,7 +1,12 @@ -use crate::{app::App, event::Sequence}; +use axum::extract::FromRef; -pub async fn resume_point(app: &App) -> Sequence { - app.boot() +use crate::{boot::app::Boot, event::Sequence}; + +pub async fn resume_point(app: &App) -> Sequence +where + Boot: FromRef, +{ + Boot::from_ref(app) .snapshot() .await .expect("boot always succeeds") -- cgit v1.2.3