pub struct Runtime { /* private fields */ }Expand description
The ironflow runtime server builder.
Runtime uses a builder pattern: create one with Runtime::new, register
webhook routes with Runtime::webhook and cron jobs with
Runtime::cron, then call Runtime::serve to start both the HTTP
server and the cron scheduler, or Runtime::run_crons to run only the
cron scheduler without an HTTP listener.
§Built-in endpoints
| Method | Path | Description |
|---|---|---|
GET | /health | Returns 200 OK with body "ok". Useful for load-balancer health checks. |
POST | user-defined | Webhook endpoints registered via Runtime::webhook. |
§Examples
use ironflow_runtime::prelude::*;
#[tokio::main]
async fn main() -> Result<(), ironflow_runtime::error::RuntimeError> {
Runtime::new()
.webhook("/hooks/deploy", WebhookAuth::github("secret"), |payload| async move {
println!("deploy triggered: {payload}");
})
.cron("0 0 * * * *", "hourly-sync", || async {
println!("syncing...");
})
.serve("0.0.0.0:3000")
.await?;
Ok(())
}Implementations§
Source§impl Runtime
impl Runtime
Sourcepub fn new() -> Self
pub fn new() -> Self
Creates a new, empty Runtime with no webhooks or cron jobs.
§Examples
use ironflow_runtime::runtime::Runtime;
let runtime = Runtime::new();Sourcepub fn max_body_size(self, bytes: usize) -> Self
pub fn max_body_size(self, bytes: usize) -> Self
Set the maximum allowed body size for webhook payloads.
Requests exceeding this limit are rejected by axum before reaching the handler. Defaults to 2 MiB.
§Examples
use ironflow_runtime::runtime::Runtime;
let runtime = Runtime::new().max_body_size(512 * 1024); // 512 KiBSourcepub fn max_concurrent_handlers(self, limit: usize) -> Self
pub fn max_concurrent_handlers(self, limit: usize) -> Self
Set the maximum number of concurrently running webhook handlers.
When the limit is reached, new webhook requests still receive 202 Accepted but their handlers are queued until a slot is available. Defaults to 64.
§Panics
Panics if limit is 0.
§Examples
use ironflow_runtime::runtime::Runtime;
let runtime = Runtime::new().max_concurrent_handlers(16);Sourcepub fn with_shutdown<F>(self, signal: F) -> Self
pub fn with_shutdown<F>(self, signal: F) -> Self
Override the default shutdown signal (Ctrl+C / SIGTERM).
By default, Runtime::serve and Runtime::run_crons block until
the process receives Ctrl+C or SIGTERM. Use this method to provide
a custom future that resolves when the runtime should shut down.
This is useful in tests where you want to trigger a clean shutdown
(including scheduler.shutdown()) without relying on OS signals.
§Examples
use ironflow_runtime::runtime::Runtime;
use tokio::sync::oneshot;
let (tx, rx) = oneshot::channel::<()>();
let rt = Runtime::new()
.with_shutdown(async { let _ = rx.await; })
.cron("0 */5 * * * *", "check", || async {});
// In another task: tx.send(()) to trigger shutdown.
rt.run_crons().await?;Sourcepub fn webhook<F, Fut>(self, path: &str, auth: WebhookAuth, handler: F) -> Self
pub fn webhook<F, Fut>(self, path: &str, auth: WebhookAuth, handler: F) -> Self
Registers a webhook route.
The handler receives the parsed JSON body as a serde_json::Value.
When a request arrives, the server verifies authentication using auth,
then spawns the handler in the background and immediately returns
202 Accepted to the caller.
§Arguments
path- The URL path to listen on (e.g."/hooks/github").auth- TheWebhookAuthstrategy for this endpoint.handler- An async function receiving the JSON payload.
§Examples
use ironflow_runtime::prelude::*;
let runtime = Runtime::new()
.webhook("/hooks/github", WebhookAuth::github("secret"), |payload| async move {
println!("payload: {payload}");
});Sourcepub fn cron<F, Fut>(self, schedule: &str, name: &str, handler: F) -> Self
pub fn cron<F, Fut>(self, schedule: &str, name: &str, handler: F) -> Self
Registers a cron job.
The schedule uses a 6-field cron expression (seconds granularity):
sec min hour day-of-month month day-of-week.
§Arguments
schedule- A 6-field cron expression, e.g."0 */5 * * * *"for every 5 minutes.name- A human-readable name for logging.handler- An async function to execute on each tick.
§Examples
use ironflow_runtime::prelude::*;
let runtime = Runtime::new()
.cron("0 0 * * * *", "hourly-cleanup", || async {
println!("cleaning up...");
});Sourcepub fn into_router(self) -> Router
pub fn into_router(self) -> Router
Consumes the runtime and returns only the axum Router.
Cron jobs are not started. This is useful for testing the HTTP
layer in isolation without side-effects (e.g. with
tower::ServiceExt::oneshot).
§Examples
use ironflow_runtime::prelude::*;
let router = Runtime::new()
.webhook("/hooks/test", WebhookAuth::none(), |_payload| async {})
.into_router();Sourcepub async fn run_crons(self) -> Result<(), RuntimeError>
pub async fn run_crons(self) -> Result<(), RuntimeError>
Starts only the cron scheduler, blocking until a shutdown signal is
received (Ctrl+C / SIGTERM).
Unlike Runtime::serve, this does not start an HTTP server. Any
registered webhooks are ignored (a warning is logged if webhooks were
registered).
§Errors
Returns an error if:
- The cron scheduler fails to initialise or a cron expression is invalid.
- The scheduler fails to shut down cleanly.
§Examples
use ironflow_runtime::prelude::*;
#[tokio::main]
async fn main() -> Result<(), ironflow_runtime::error::RuntimeError> {
Runtime::new()
.cron("0 0 * * * *", "hourly-sync", || async {
println!("syncing...");
})
.run_crons()
.await?;
Ok(())
}Sourcepub async fn serve(self, addr: &str) -> Result<(), RuntimeError>
pub async fn serve(self, addr: &str) -> Result<(), RuntimeError>
Starts the HTTP server and cron scheduler, blocking until shutdown.
This method:
- Loads environment variables from
.envviadotenvy. - Starts the
tokio_cron_schedulerscheduler with all registered cron jobs. - Builds an Axum router with all registered webhook
routes plus a
GET /healthendpoint. - Binds to
addrand serves until aCtrl+Csignal is received. - Gracefully shuts down the scheduler before returning.
If you only need cron jobs without an HTTP server, use
Runtime::run_crons instead.
§Errors
Returns an error if:
- The cron scheduler fails to initialise or a cron expression is invalid.
- The TCP listener cannot bind to
addr. - The Axum server encounters a fatal I/O error.
§Examples
use ironflow_runtime::prelude::*;
#[tokio::main]
async fn main() -> Result<(), ironflow_runtime::error::RuntimeError> {
Runtime::new()
.serve("127.0.0.1:3000")
.await?;
Ok(())
}