Webhooks¶
SnerdMQ can dispatch tasks via HTTP POST requests to any URL, enabling serverless execution patterns. Instead of running handlers locally, SnerdMQ sends the task payload to your endpoint — perfect for distributed architectures, serverless functions, and cross-service orchestration.
How It Works¶
When you set a webhook_url on a task:
- SnerdMQ skips local handlers entirely
- Sends an HTTP POST to your URL with the task payload as the JSON body
- Includes the
X-SnerdMQ-Event: Executeheader - If your endpoint returns a non-200 status, the task is retried
- If the task permanently fails (max retries reached), SnerdMQ fires a final POST with
X-SnerdMQ-Event: MaxRetriesReached
Webhook Request Format¶
Headers:
Body: The task's data payload as JSON.
DLQ notification (max retries reached):
Code Examples¶
Handling Webhook Requests (Server Side)¶
Here's how to receive SnerdMQ webhook dispatches in your server:
app.post('/webhook/transcode', (req, res) => {
const event = req.headers['x-snerdmq-event'];
if (event === 'Execute') {
// Normal task execution
const { file, format } = req.body;
transcodeVideo(file, format);
res.status(200).json({ status: 'ok' });
} else if (event === 'MaxRetriesReached') {
// DLQ notification — task permanently failed
console.error('Task permanently failed:', req.body);
res.status(200).json({ status: 'acknowledged' });
}
});
@app.post("/webhook/transcode")
async def handle_webhook(request: Request):
event = request.headers.get("X-SnerdMQ-Event")
body = await request.json()
if event == "Execute":
transcode_video(body["file"], body["format"])
return {"status": "ok"}
elif event == "MaxRetriesReached":
logger.error(f"Task permanently failed: {body}")
return {"status": "acknowledged"}
Use Cases¶
- Stateless Polyglot Workers — Run the robust SnerdMQ daemon or
snerd-goembedded engine as the broker, and point webhooks to stateless, fast microservices in Rust, C++, or any language. SnerdMQ handles persistence, timeouts, and retries natively, while your worker remains a pure HTTP function.
Go (Producer & Broker):
queue := snerd.NewAnyQueue("go-broker", 100, 1*time.Second)
webhookURL := "http://localhost:3000/api/worker/send-push"
task, _ := snerd.CreateTask("SEND_PUSH", map[string]interface{}{"user_id": 1001}, 3, 0.5)
task.WebhookUrl = &webhookURL
queue.EnqueueSnerdTask(task)
Rust (Worker Pools Broker Receiver):
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct SnerdWebhookPayload {
task_id: String,
task_type: String,
#[serde(rename = "data")]
parameters: String,
}
// The receiver places the webhook into an isolated snerd-rust pool!
async fn handle_send_push(
State(queue): State<Arc<SnerdQueue>>,
Json(payload): Json<SnerdWebhookPayload>
) -> StatusCode {
// 1. Enqueue it in an isolated pool for reliable execution and retry recovery
let mut task = RetryableTask::new(
payload.task_id, payload.task_type, payload.parameters,
3, 1.0, None, None, None, None, None, None, None, None,
Some("push-pool".to_string()) // pool
);
// 2. Acknowledge the HTTP request immediately
match queue.enqueue(task) {
Ok(_) => StatusCode::OK,
Err(_) => StatusCode::INTERNAL_SERVER_ERROR
}
}
Webhook + DLQ¶
When a webhook task permanently fails (reaches max_retries), SnerdMQ automatically sends a final HTTP POST to the same webhook_url with the X-SnerdMQ-Event: MaxRetriesReached header. This means you don't need SDK-side max retry handlers for webhook tasks — your endpoint handles both execution and failure notification.