From 16c19c0904fdd7b41f685e853670f7c7beebe7cb Mon Sep 17 00:00:00 2001 From: Spencer Ferris <3319370+spencewenski@users.noreply.github.com> Date: Sun, 12 May 2024 00:49:36 -0700 Subject: [PATCH] Pass config and context by reference in all public APIs https://github.com/roadster-rs/roadster/issues/61 --- examples/minimal/src/app.rs | 8 ++-- src/app.rs | 64 +++++++++++++++++---------- src/app_context.rs | 2 +- src/service/http/service.rs | 2 +- src/service/mod.rs | 2 +- src/service/registry.rs | 4 +- src/service/worker/sidekiq/service.rs | 6 +-- 7 files changed, 52 insertions(+), 36 deletions(-) diff --git a/examples/minimal/src/app.rs b/examples/minimal/src/app.rs index fb069dd0..a499a2b6 100644 --- a/examples/minimal/src/app.rs +++ b/examples/minimal/src/app.rs @@ -29,17 +29,17 @@ impl RoadsterApp for App { async fn services( registry: &mut ServiceRegistry, - context: AppContext, + context: &AppContext, ) -> anyhow::Result<()> { registry - .register_builder(HttpService::builder(BASE, &context).router(controller::routes(BASE))) + .register_builder(HttpService::builder(BASE, context).router(controller::routes(BASE))) .await?; registry .register_builder( - SidekiqWorkerService::builder(context.clone()) + SidekiqWorkerService::builder(context) .await? - .register_app_worker(ExampleWorker::build(&context))?, + .register_app_worker(ExampleWorker::build(context))?, ) .await?; diff --git a/src/app.rs b/src/app.rs index 558aa216..7f0bd53b 100644 --- a/src/app.rs +++ b/src/app.rs @@ -139,8 +139,8 @@ where } } - let mut service_registry = ServiceRegistry::new(context.clone()); - A::services(&mut service_registry, context.clone()).await?; + let mut service_registry = ServiceRegistry::new(&context); + A::services(&mut service_registry, &context).await?; #[cfg(feature = "cli")] for (_name, service) in service_registry.services.iter() { @@ -171,29 +171,45 @@ where let cancel_token = cancel_token.clone(); join_set.spawn(Box::pin(async move { info!(service=%name, "Running service"); - service.run(context, cancel_token).await + service.run(&context, cancel_token).await })); } // Task to clean up resources when gracefully shutting down. - join_set.spawn(cancel_on_error( - cancel_token.clone(), - context.clone(), - graceful_shutdown( - token_shutdown_signal(cancel_token.clone()), - A::graceful_shutdown(context.clone()), - context.clone(), - ), - )); + { + let context = context.clone(); + let cancel_token = cancel_token.clone(); + let app_graceful_shutdown = { + let context = context.clone(); + Box::pin(async move { A::graceful_shutdown(&context).await }) + }; + join_set.spawn(Box::pin(async move { + cancel_on_error( + cancel_token.clone(), + &context, + graceful_shutdown( + token_shutdown_signal(cancel_token.clone()), + app_graceful_shutdown, + context.clone(), + ), + ) + .await + })); + } // Task to listen for the signal to gracefully shutdown, and trigger other tasks to stop. - let graceful_shutdown_signal = graceful_shutdown_signal( - cancel_token.clone(), - A::graceful_shutdown_signal(context.clone()), - ); - join_set.spawn(cancel_token_on_signal_received( - graceful_shutdown_signal, - cancel_token.clone(), - )); + { + let context = context.clone(); + let app_graceful_shutdown_signal = { + let context = context.clone(); + Box::pin(async move { A::graceful_shutdown_signal(&context).await }) + }; + let graceful_shutdown_signal = + graceful_shutdown_signal(cancel_token.clone(), app_graceful_shutdown_signal); + join_set.spawn(cancel_token_on_signal_received( + graceful_shutdown_signal, + cancel_token.clone(), + )); + } // Wait for all the tasks to complete. while let Some(result) = join_set.join_next().await { @@ -259,7 +275,7 @@ pub trait App: Send + Sync { /// Provide the services to run in the app. async fn services( _registry: &mut ServiceRegistry, - _context: AppContext, + _context: &AppContext, ) -> anyhow::Result<()> { Ok(()) } @@ -267,14 +283,14 @@ pub trait App: Send + Sync { /// Override to provide a custom shutdown signal. Roadster provides some default shutdown /// signals, but it may be desirable to provide a custom signal in order to, e.g., shutdown the /// server when a particular API is called. - async fn graceful_shutdown_signal(_context: AppContext) { + async fn graceful_shutdown_signal(_context: &AppContext) { let _output: () = future::pending().await; } /// Override to provide custom graceful shutdown logic to clean up any resources created by /// the app. Roadster will take care of cleaning up the resources it created. #[instrument(skip_all)] - async fn graceful_shutdown(_context: AppContext) -> anyhow::Result<()> { + async fn graceful_shutdown(_context: &AppContext) -> anyhow::Result<()> { Ok(()) } } @@ -334,7 +350,7 @@ async fn token_shutdown_signal(cancellation_token: CancellationToken) { async fn cancel_on_error( cancellation_token: CancellationToken, - context: AppContext, + context: &AppContext, f: F, ) -> anyhow::Result where diff --git a/src/app_context.rs b/src/app_context.rs index 1a59c3f3..8577853c 100644 --- a/src/app_context.rs +++ b/src/app_context.rs @@ -12,7 +12,7 @@ pub struct AppContext { } impl AppContext { - pub fn new( + pub(crate) fn new( config: AppConfig, #[cfg(feature = "db-sql")] db: DatabaseConnection, #[cfg(feature = "sidekiq")] redis_enqueue: sidekiq::RedisPool, diff --git a/src/service/http/service.rs b/src/service/http/service.rs index 188766f3..45acd8e8 100644 --- a/src/service/http/service.rs +++ b/src/service/http/service.rs @@ -68,7 +68,7 @@ impl AppService for HttpService { async fn run( &self, - app_context: AppContext, + app_context: &AppContext, cancel_token: CancellationToken, ) -> anyhow::Result<()> { let server_addr = app_context.config().service.http.custom.address.url(); diff --git a/src/service/mod.rs b/src/service/mod.rs index e32002c2..600053d5 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -47,7 +47,7 @@ pub trait AppService: Send + Sync { /// the service. async fn run( &self, - app_context: AppContext, + app_context: &AppContext, cancel_token: CancellationToken, ) -> anyhow::Result<()>; } diff --git a/src/service/registry.rs b/src/service/registry.rs index 4eace7f1..16a2e312 100644 --- a/src/service/registry.rs +++ b/src/service/registry.rs @@ -15,9 +15,9 @@ where } impl ServiceRegistry { - pub(crate) fn new(context: AppContext) -> Self { + pub(crate) fn new(context: &AppContext) -> Self { Self { - context, + context: context.clone(), services: Default::default(), } } diff --git a/src/service/worker/sidekiq/service.rs b/src/service/worker/sidekiq/service.rs index 874489ce..77204b1d 100644 --- a/src/service/worker/sidekiq/service.rs +++ b/src/service/worker/sidekiq/service.rs @@ -47,7 +47,7 @@ impl AppService for SidekiqWorkerService { async fn run( &self, - _app_context: AppContext, + _app_context: &AppContext, cancel_token: CancellationToken, ) -> anyhow::Result<()> { let processor = self.processor.clone(); @@ -80,11 +80,11 @@ impl AppService for SidekiqWorkerService { impl SidekiqWorkerService { pub async fn builder( - context: AppContext, + context: &AppContext, ) -> anyhow::Result> where A: App + 'static, { - SidekiqWorkerServiceBuilder::with_default_processor(&context, None).await + SidekiqWorkerServiceBuilder::with_default_processor(context, None).await } }