raceway

Crates.ioraceway
lib.rsraceway
version0.1.0
created_at2025-11-04 00:02:40.652452+00
updated_at2025-11-04 00:02:40.652452+00
descriptionOfficial Rust SDK for Raceway - race condition detection and distributed tracing
homepagehttps://mode7labs.github.io/raceway
repositoryhttps://github.com/mode7labs/raceway
max_upload_size
id1915467
size125,456
Joe Logan (jlognn)

documentation

https://mode7labs.github.io/raceway/sdks/rust

README

raceway-rust

Official Rust SDK for Raceway - Race condition detection and distributed tracing for Rust applications.

📚 Full Documentation

Features

  • Automatic context propagation using tokio::task_local!
  • Axum middleware support
  • Distributed tracing across service boundaries (W3C Trace Context)
  • Race condition and concurrency bug detection
  • Automatic batching and background flushing

Installation

Add to your Cargo.toml:

[dependencies]
raceway = "0.1"
tokio = { version = "1.35", features = ["full", "macros"] }

Quick Start

use axum::{
    extract::State,
    routing::post,
    Json, Router,
};
use raceway::RacewayClient;
use serde::{Deserialize, Serialize};
use std::sync::Arc;

#[derive(Deserialize)]
struct TransferRequest {
    from: String,
    to: String,
    amount: i64,
}

#[tokio::main]
async fn main() {
    let raceway = Arc::new(RacewayClient::new(
        "http://localhost:8080",
        "my-service"
    ));

    let app = Router::new()
        .route("/api/transfer", post(transfer))
        .layer(axum::middleware::from_fn_with_state(
            raceway.clone(),
            RacewayClient::middleware,
        ))
        .with_state(raceway);

    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
        .await.unwrap();

    axum::serve(listener, app).await.unwrap();
}

async fn transfer(
    State(raceway): State<Arc<RacewayClient>>,
    Json(req): Json<TransferRequest>,
) -> Json<serde_json::Value> {
    raceway.track_function_call("transfer", &req);

    // Track state changes
    let balance = get_balance(&req.from).await;
    raceway.track_state_change(
        &format!("{}.balance", req.from),
        None::<i64>, balance, "Read"
    );

    set_balance(&req.from, balance - req.amount).await;
    raceway.track_state_change(
        &format!("{}.balance", req.from),
        Some(balance), balance - req.amount, "Write"
    );

    Json(serde_json::json!({ "success": true }))
}

Distributed Tracing

Propagate traces across service boundaries:

use reqwest::Client;

async fn checkout(
    State(raceway): State<Arc<RacewayClient>>,
) -> Json<serde_json::Value> {
    // Get propagation headers
    let headers = raceway.propagation_headers(None).unwrap();

    // Call downstream service
    let client = Client::new();
    client
        .post("http://inventory-service/reserve")
        .header("traceparent", headers.get("traceparent").unwrap())
        .header("raceway-clock", headers.get("raceway-clock").unwrap())
        .send()
        .await;

    Json(serde_json::json!({ "success": true }))
}

Documentation

Examples

See examples/rust-banking for a complete Axum application with Raceway integration.

License

MIT

Links

Commit count: 0

cargo fmt