Skip to content

Commit

Permalink
docs: Add to AppContext book docs
Browse files Browse the repository at this point in the history
  • Loading branch information
spencewenski committed Jan 31, 2025
1 parent 3e30bd9 commit fd7903b
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 19 deletions.
4 changes: 3 additions & 1 deletion book/examples/app-context/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ publish = false

[dependencies]
roadster = { path = "../../.." }
axum = { workspace = true }
axum = { workspace = true }
async-trait = { workspace = true }
anyhow = { workspace = true }
57 changes: 57 additions & 0 deletions book/examples/app-context/src/app.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use crate::state::CustomState;
use anyhow::anyhow;
use async_trait::async_trait;
use axum::extract::FromRef;
use roadster::app::context::{AppContext, AppContextWeak};
use roadster::app::RoadsterApp;
use roadster::error::RoadsterResult;
use roadster::health::check::{CheckResponse, HealthCheck, Status};
use roadster::util::empty::Empty;
use std::time::Duration;

pub type App = RoadsterApp<CustomState, Empty, Empty>;

pub struct ExampleHealthCheck {
// Prevent reference cycle because the `ExampleHealthCheck` is also stored in the `AppContext`
context: AppContextWeak,
}

#[async_trait]
impl HealthCheck for ExampleHealthCheck {
fn name(&self) -> String {
"example".to_string()
}

fn enabled(&self) -> bool {
true
}

async fn check(&self) -> RoadsterResult<CheckResponse> {
// Upgrade the `AppContext` in order to use it
let _context = self
.context
.upgrade()
.ok_or_else(|| anyhow!("Could not upgrade AppContextWeak"))?;

Ok(CheckResponse::builder()
.status(Status::Ok)
.latency(Duration::from_secs(0))
.build())
}
}

pub fn build_app() -> App {
RoadsterApp::builder()
.state_provider(|context| {
Ok(CustomState {
context,
custom_field: "Custom Field".to_string(),
})
})
.add_health_check_provider(|registry, state| {
// Downgrade the context before providing it to the `ExampleHealthCheck`
let context = AppContext::from_ref(state).downgrade();
registry.register(ExampleHealthCheck { context })
})
.build()
}
19 changes: 2 additions & 17 deletions book/examples/app-context/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,2 @@
use axum::extract::FromRef;
use roadster::app::context::AppContext;

#[derive(FromRef)]
pub struct CustomState {
custom_field: String,
context: AppContext,
}

impl CustomState {
pub fn new(custom_field: String, context: AppContext) -> Self {
Self {
custom_field,
context,
}
}
}
pub mod app;
pub mod state;
8 changes: 8 additions & 0 deletions book/examples/app-context/src/state.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use axum::extract::FromRef;
use roadster::app::context::AppContext;

#[derive(Clone, FromRef)]
pub struct CustomState {
pub context: AppContext,
pub custom_field: String,
}
24 changes: 23 additions & 1 deletion book/src/features/app-context.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,29 @@ directly, or you can define your own state type that can be used by both Roadste
implementing [FromRef](https://docs.rs/axum-core/latest/axum_core/extract/trait.FromRef.html).

```rust,ignore
{{#include ../../examples/app-context/src/lib.rs}}
{{#include ../../examples/app-context/src/state.rs}}
```

## `Provide` and `ProvideRef`

🛠️ todo 🛠️

- https://docs.rs/roadster/latest/roadster/app/context/trait.Provide.html
- https://docs.rs/roadster/latest/roadster/app/context/trait.ProvideRef.html

## Weak reference

In some cases, it can be useful to have a weak reference to the `AppContext` state in order to prevent reference cycles
for things that are included in the `AppContext` but also need a reference to the `AppContext`. For example, the
`AppContext` keeps a reference to the `HealthCheck`s, and most `HealthCheck`s need to use the `AppContext`.

To get a weak reference to the `AppContext`'s state,
use [AppContext#downgrade](https://docs.rs/roadster/latest/roadster/app/context/struct.AppContext.html#method.downgrade)
to get a new instance
of [AppContextWeak](https://docs.rs/roadster/latest/roadster/app/context/struct.AppContextWeak.html).

```rust,ignore
{{#include ../../examples/app-context/src/app.rs:12:}}
```

## Docs.rs links
Expand Down

0 comments on commit fd7903b

Please sign in to comment.