rust 64 lines · 9 steps

Offloading work with a channel in Axum

An Axum handler enqueues background jobs onto a Tokio mpsc channel instead of doing slow work inline.

Explained by highlit
1use std::sync::Arc;
2 
3use axum::{
4 extract::State,
5 http::StatusCode,
6 routing::post,
7 Json, Router,
8};
9use serde::Deserialize;
10use tokio::sync::mpsc::{self, Sender};
11use uuid::Uuid;
12 
13#[derive(Clone)]
14pub struct AppState {
15 jobs: Sender<Job>,
16}
17 
18#[derive(Debug)]
19pub enum Job {
20 SendWelcomeEmail { user_id: Uuid, email: String },
21 ResizeAvatar { user_id: Uuid, url: String },
22}
23 
24pub fn build(worker_buffer: usize) -> (Router, mpsc::Receiver<Job>) {
25 let (tx, rx) = mpsc::channel(worker_buffer);
26 let state = Arc::new(AppState { jobs: tx });
27 
28 let router = Router::new()
29 .route("/users", post(create_user))
30 .with_state(state);
31 
32 (router, rx)
33}
34 
35#[derive(Deserialize)]
36struct CreateUser {
37 email: String,
38 avatar_url: Option<String>,
39}
40 
41async fn create_user(
42 State(state): State<Arc<AppState>>,
43 Json(payload): Json<CreateUser>,
44) -> Result<StatusCode, StatusCode> {
45 let user_id = Uuid::new_v4();
46 
47 state
48 .jobs
49 .send(Job::SendWelcomeEmail {
50 user_id,
51 email: payload.email,
52 })
53 .await
54 .map_err(|_| StatusCode::SERVICE_UNAVAILABLE)?;
55 
56 if let Some(url) = payload.avatar_url {
57 state
58 .jobs
59 .try_send(Job::ResizeAvatar { user_id, url })
60 .map_err(|_| StatusCode::SERVICE_UNAVAILABLE)?;
61 }
62 
63 Ok(StatusCode::ACCEPTED)
64}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Sharing a channel sender through Axum state lets handlers hand off slow work and respond immediately.
  2. 2Choosing send versus try_send decides whether a handler waits for buffer space or fails fast under load.
  3. 3Returning 202 Accepted signals that work was queued, not that it finished.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Offloading work with a channel in Axum — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code