Rust SDK
The Rust SDK for writing TaskDaemon handlers.Installation
Copy
[dependencies]
taskdaemon-handler = "0.1"
serde_json = "1.0"
Basic Usage
Copy
use taskdaemon_handler::{run, success, Task};
use serde_json::json;
fn main() {
run(|task: Task| {
let name = task.task_data
.get("name")
.and_then(|v| v.as_str())
.unwrap_or("World");
success(json!({
"message": format!("Hello, {}!", name)
}))
});
}
Task Struct
Copy
#[derive(Deserialize)]
pub struct Task {
pub task_id: String,
pub task_type: String,
pub task_data: serde_json::Value,
pub attempt: u32, // Current attempt (starts at 0)
}
Result Functions
Copy
use taskdaemon_handler::{success, error, Result};
use serde_json::json;
// Success with result
return success(json!({"result": "value"}));
// Non-retryable error
return error("invalid input", false);
// Retryable error
return error("service unavailable", true);
Result enum:
Copy
#[derive(Serialize)]
#[serde(tag = "status", rename_all = "lowercase")]
pub enum Result<T: Serialize> {
Success { result: T },
Error { error: String, retryable: bool },
}
Complete Example
Copy
use taskdaemon_handler::{run, success, error, Task, Result};
use serde_json::{json, Value};
use base64::{Engine, engine::general_purpose::STANDARD};
use image::{ImageFormat, imageops::FilterType};
use std::io::Cursor;
fn resize_image(task: Task) -> Result<Value> {
let url = match task.task_data.get("image_url").and_then(|v| v.as_str()) {
Some(u) => u,
None => return error("missing image_url", false),
};
let width = match task.task_data.get("width").and_then(|v| v.as_u64()) {
Some(w) => w as u32,
None => return error("missing width", false),
};
let height = match task.task_data.get("height").and_then(|v| v.as_u64()) {
Some(h) => h as u32,
None => return error("missing height", false),
};
// Download
let response = match reqwest::blocking::get(url) {
Ok(r) => r,
Err(e) => return error(e.to_string(), true), // Retryable
};
let bytes = match response.bytes() {
Ok(b) => b,
Err(e) => return error(e.to_string(), true),
};
// Decode and resize
let img = match image::load_from_memory(&bytes) {
Ok(i) => i,
Err(e) => return error(e.to_string(), false),
};
let resized = img.resize_exact(width, height, FilterType::Lanczos3);
// Encode
let mut buf = Cursor::new(Vec::new());
if let Err(e) = resized.write_to(&mut buf, ImageFormat::Png) {
return error(e.to_string(), false);
}
let b64 = STANDARD.encode(buf.into_inner());
success(json!({
"data": b64,
"size": [width, height],
"format": "png"
}))
}
fn main() {
run(resize_image);
}
Error Handling
JSON parsing errors are automatically handled by the SDK. Your handler only receives validTask objects.
For explicit error handling, use the error function:
Copy
fn handler(task: Task) -> Result<Value> {
let required = match task.task_data.get("required") {
Some(v) => v,
None => return error("missing required field", false),
};
success(json!({"value": required}))
}
Dockerfile
Copy
FROM rust:1.75 AS builder
WORKDIR /app
COPY Cargo.toml Cargo.lock ./
COPY src ./src
RUN cargo build --release
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*
COPY --from=builder /app/target/release/handler /handler
CMD ["/handler"]
Copy
FROM rust:1.75-alpine AS builder
RUN apk add --no-cache musl-dev
WORKDIR /app
COPY Cargo.toml Cargo.lock ./
COPY src ./src
RUN cargo build --release --target x86_64-unknown-linux-musl
FROM scratch
COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/handler /handler
CMD ["/handler"]
Handler Configuration
Copy
[handlers.resize]
image = "rust-handler:latest"
instances = 4
timeout = 30