procwire-client 1.0.0

Rust client SDK for Procwire IPC — high-performance binary protocol for Node.js ↔ Rust communication
Documentation

procwire-client

Crates.io Documentation License: MIT

Rust client SDK for Procwire v2.0 IPC protocol.

This crate enables Rust workers (child processes) to communicate with a Node.js parent process running @procwire/core using a high-performance binary protocol.

Features

  • High Performance: Binary protocol with MsgPack serialization, achieving >1 GB/s throughput
  • Zero-copy: Uses bytes::BytesMut for efficient buffer management
  • Async/await: Built on Tokio for non-blocking I/O
  • Cross-platform: Works on Linux, macOS, and Windows
  • Type-safe: Strongly typed handlers with Serde integration
  • Streaming: Support for chunked responses and backpressure
  • Cancellation: Full abort signal support with CancellationToken

Installation

Add to your Cargo.toml:

[dependencies]
procwire-client = "0.1"
tokio = { version = "1", features = ["full"] }
serde = { version = "1", features = ["derive"] }

Quick Start

use procwire_client::ClientBuilder;
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
struct EchoRequest {
    message: String,
}

#[derive(Serialize, Deserialize)]
struct EchoResponse {
    message: String,
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = ClientBuilder::new()
        .method("echo", |ctx, payload: EchoRequest| async move {
            ctx.respond(&EchoResponse {
                message: payload.message,
            })
            .await
        })
        .build()
        .await?;

    client.run().await?;
    Ok(())
}

Architecture

Procwire uses a dual-channel architecture:

  • Control Plane (stdio): JSON-RPC for the $init handshake
  • Data Plane (named pipe/Unix socket): Binary protocol for high-throughput communication
┌─────────────────┐                    ┌─────────────────┐
│  Node.js Parent │                    │   Rust Worker   │
│ (@procwire/core)│                    │ (this crate)    │
├─────────────────┤                    ├─────────────────┤
│                 │◄── $init (JSON) ───│                 │
│                 │                    │                 │
│                 │◄═══ Binary ═══════►│                 │
│                 │   (Named Pipe)     │                 │
└─────────────────┘                    └─────────────────┘

Wire Format

All data plane messages use an 11-byte binary header:

┌──────────┬───────┬──────────┬──────────┬──────────────────────┐
│ Method ID│ Flags │ Req ID   │ Length   │ Payload              │
│ 2 bytes  │ 1 byte│ 4 bytes  │ 4 bytes  │ N bytes              │
│ uint16 BE│       │ uint32 BE│ uint32 BE│ (MsgPack)            │
└──────────┴───────┴──────────┴──────────┴──────────────────────┘

Response Types

Simple Response

ctx.respond(&data).await?;

Acknowledgment (for fire-and-forget)

ctx.ack().await?;

Streaming Response

for chunk in chunks {
    ctx.chunk(&chunk).await?;
}
ctx.end().await?;

Error Response

ctx.error("Something went wrong").await?;

Events (Fire-and-Forget)

Send events to the parent process:

client.emit("progress", &ProgressEvent { percent: 50 }).await?;

Cancellation Support

Handlers can respond to abort signals from the parent:

.method("long_task", |ctx, _payload: ()| async move {
    loop {
        if ctx.is_cancelled() {
            return Ok(());
        }

        // Or use select! for async operations
        tokio::select! {
            _ = ctx.cancelled() => return Ok(()),
            result = do_work() => {
                ctx.chunk(&result).await?;
            }
        }
    }
})

Configuration

ClientBuilder::new()
    .max_concurrent_handlers(256)  // Limit concurrent handler tasks
    .backpressure_timeout(Duration::from_secs(30))
    .method("handler", |ctx, req| async move { /* ... */ })
    .build()
    .await?;

Platform Support

Platform Transport
Linux Unix Domain Socket
macOS Unix Domain Socket
Windows Named Pipe

Related Projects

  • procwire - Node.js/TypeScript parent library (@procwire/core)

License

MIT License - see LICENSE for details.