1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
//! Background-job entry point.
//!
//! A "job" in micro is a binary that runs to completion (queue consumer,
//! scheduled task, one-shot migration runner) rather than serving gRPC.
//! It shares the service crate, so it sees the same `State` and the same
//! `tonin::auth` setup — but it doesn't bind a port and doesn't run
//! the inbound auth layer.
//!
//! ## What `bootstrap` does
//!
//! 1. Initialize OTel (same `crate::telemetry::init` the server uses,
//! so traces / metrics export to the same collector).
//! 2. Mint a **service-identity** `AuthCtx` via [`crate::auth::service_token`].
//! There's no incoming request to extract auth from, so the framework
//! mints one representing *this service* and the job propagates it on
//! outbound RPCs.
//! 3. Build a [`crate::State`] from env (Postgres + Redis lazily, same as `main.rs`).
//!
//! ## Usage
//!
//! ```ignore
//! use tonin::prelude::*;
//!
//! #[tokio::main]
//! async fn main() -> Result<()> {
//! let ctx = tonin::job::bootstrap("greeter-cleanup").await?;
//!
//! // Use ctx.state.pg() / ctx.state.redis() for queries.
//! // Use ctx.auth.propagate(&mut req) on outbound calls so the
//! // callee sees a service principal rather than anonymous.
//! tracing::info!(job = "greeter-cleanup", subject = %ctx.auth.subject, "starting");
//!
//! // ... your job logic ...
//! Ok(())
//! }
//! ```
//!
//! ## Spawn pitfall
//!
//! [`crate::auth::CURRENT_AUTH`] is task-local and gets set by the
//! server's auth layer; **jobs don't set it** because there's no
//! inbound request. If you `tokio::spawn` from inside a job, capture
//! `ctx.auth` before the spawn and pass it explicitly.
use crateAuthCtx;
use crate;
use crateState;
/// Bootstrap output: identity + pre-wired storage. Cheap to clone.
/// Initialize telemetry, mint a service-identity token, and resolve
/// state. Designed to be the second line of every job binary's `main`
/// (the first being `#[tokio::main]`).
///
/// **Errors:** any of (a) the service-token minter isn't configured
/// (`TONIN_AUTH_SERVICE_TOKEN_URL` unset), (b) the auth service is
/// unreachable, (c) `DATABASE_URL` / `REDIS_URL` was set but the dep
/// is unreachable. All three are deploy-time problems; failing the
/// job at bootstrap is the right move.
pub async