Skip to main content
The Rust workflow SDK allows you to build WebAssembly-compiled workflows that react to live streams, query historical data, and write events back to Slung or external systems.

Installation

Add the SDK to your Cargo.toml:
[dependencies]
slung = "0.1"

Quick Start

Create a reactive workflow that monitors a live stream:
use slung::prelude::*;

#[main]
fn main() -> Result<()> {
    // Subscribe to live stream updates
    let handle = query_live("AVG:temp:[sensor=1]")?;
    poll_handle(handle, on_event, 100.0)?;

    Ok(())
}

fn on_event(event: Event, alert_threshold: f64) -> Result<()> {
    if event.value > alert_threshold {
        println!("event timestamp={} value={}", event.timestamp, event.value);
        for producer in event.producers {
            writeback_ws(producer, "ALERT: threshold exceeded")?;
        }
    }

    Ok(())
}

Key Concepts

Host Functions

Workflows execute in a WebAssembly sandbox and communicate with Slung through host functions. These functions enable:
  • Querying live and historical data
  • Writing events
  • Sending writeback messages to WebSocket clients
  • Making HTTP requests

Event Model

Events received from live queries contain:
pub struct Event {
    pub timestamp: i64,      // Unix microseconds
    pub value: f64,          // Numeric value
    pub tags: Vec<String>,   // Event tags
    pub producers: Vec<u64>, // Producer connection IDs
}

Query Syntax

Live and historical queries use the format:
AGGREGATE:series:[tag1,tag2,...]
Supported aggregates:
  • AVG - Running average
  • SUM - Cumulative sum
  • MIN - Minimum value
  • MAX - Maximum value

Querying Data

Live Queries

Register a live query to receive streaming updates:
let handle = query_live("AVG:cpu:[host=server1]")?;
poll_handle(handle, |event, _| {
    println!("CPU average: {}", event.value);
    Ok(())
}, ())?;

Historical Queries

Query aggregated historical data:
let avg_temp = query_history("AVG:temp:[sensor=1]")?;
let max_cpu = query_history("MAX:cpu:[host=server1]")?;

println!("Average temperature: {}", avg_temp);
println!("Max CPU usage: {}", max_cpu);

Polling Aggregate State

Poll once for the current aggregate state:
use slung::PollState;

let handle = query_live("SUM:requests:[]")?;

loop {
    if let Some(state) = poll_handle_state(handle)? {
        match state {
            PollState::Sum(total) => println!("Total requests: {}", total),
            PollState::Avg(avg) => println!("Average: {}", avg.sum / avg.count as f64),
            PollState::Min(min) => println!("Minimum: {}", min),
            PollState::Max(max) => println!("Maximum: {}", max),
        }
    }
    std::thread::sleep(std::time::Duration::from_millis(100));
}

free_handle(handle)?;

Writing Data

Writing Events

Write new events to Slung from your workflow:
let timestamp = unix_micros();
let value = 42.0;
let tags = vec!["series=derived".to_string(), "source=workflow".to_string()];

write_event(timestamp, value, tags)?;
The special tag series=<name> specifies the series name. All other tags are treated as regular tags.

Writeback to WebSocket Clients

Send messages back to WebSocket producers:
fn on_event(event: Event, _: ()) -> Result<()> {
    for producer in event.producers {
        writeback_ws(producer, "Processing complete")?;
    }
    Ok(())
}

HTTP Writeback

Make HTTP requests to external services:
use slung::WritebackMethod;

let response = writeback_http(
    "https://api.example.com/webhook",
    r#"{"alert": "threshold exceeded"}"#,
    WritebackMethod::POST
)?;

if let Some(body) = response {
    println!("Response: {:?}", String::from_utf8_lossy(&body));
}

Prelude

The slung::prelude module exports commonly used items:
use slung::prelude::*;
This includes:
  • Event struct
  • All query and write functions
  • The #[main] macro
  • Result type from std::io

Next Steps

Workflow API Reference

Complete API reference for workflow functions

Host Functions

Detailed host function reference

Build docs developers (and LLMs) love