Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

GitHub

This documentation is part of the "Projects with Books" initiative at zenOSmosis.

The source code for this project is available on GitHub.

WebSocket Server

Loading…

WebSocket Server

Relevant source files

Purpose and Scope

This document covers the simd-r-drive-ws-server WebSocket server implementation, which provides remote access to the SIMD R Drive storage engine over WebSocket connections using the Muxio RPC framework. The server accepts connections from both native Rust clients (see Native Rust Client) and Python applications (see Python WebSocket Client API), routing RPC requests to the underlying DataStore.

For information about the RPC protocol and serialization format, see Muxio RPC Framework. For details on the core storage operations being exposed, see DataStore API.


Architecture Overview

The WebSocket server is built directly on muxio-tokio-rpc-server and the Tokio async runtime, providing a high-performance, concurrent RPC endpoint for storage operations. The server acts as a thin network wrapper around DataStore, translating WebSocket RPC messages into storage API calls.

graph TB
    CLI["main()
with clap::Parser"]
MuxioServer["muxio_tokio_rpc_server::Server"]
Endpoint["muxio_rpc_service_endpoint::ServiceEndpoint"]
ServiceDef["simd_r_drive_muxio_service_definition"]
DataStore["simd_r_drive::DataStore"]
Tokio["tokio::runtime::Runtime"]
Tungstenite["tokio_tungstenite"]
CLI --> MuxioServer
 
   MuxioServer --> Endpoint
 
   MuxioServer --> Tungstenite
 
   Endpoint --> ServiceDef
 
   Endpoint --> DataStore
    
    MuxioServer -.runs on.-> Tokio
    Tungstenite -.runs on.-> Tokio

Component Stack

Sources: experiments/simd-r-drive-ws-server/Cargo.toml:1-23


Crate Structure

The server is located in the experiments/ workspace directory and has a minimal dependency footprint focused on networking and RPC:

DependencyPurposeDeclaration
simd-r-driveCore storage engineexperiments/simd-r-drive-ws-server/Cargo.toml14
simd-r-drive-muxio-service-definitionRPC service contractexperiments/simd-r-drive-ws-server/Cargo.toml15
muxio-tokio-rpc-serverRPC server runtime with WebSocket transportexperiments/simd-r-drive-ws-server/Cargo.toml16
muxio-rpc-serviceRPC service trait abstractionsexperiments/simd-r-drive-ws-server/Cargo.toml17
tokioAsync runtime executorexperiments/simd-r-drive-ws-server/Cargo.toml18
tracing-subscriberLogging subscriber with env-filterexperiments/simd-r-drive-ws-server/Cargo.toml19
tracingStructured loggingexperiments/simd-r-drive-ws-server/Cargo.toml20
clapCLI argument parsing with derive featureexperiments/simd-r-drive-ws-server/Cargo.toml21
indocIndented string literals for help textexperiments/simd-r-drive-ws-server/Cargo.toml22

Sources: experiments/simd-r-drive-ws-server/Cargo.toml:13-22


Server Initialization Flow

The server follows a standard initialization pattern: parse CLI arguments, configure logging, initialize the DataStore, create a service endpoint, and start the muxio-tokio-rpc-server.

Sources: experiments/simd-r-drive-ws-server/Cargo.toml:14-22

sequenceDiagram
    participant Main as "main()"
    participant CLI as "clap::Parser::parse()"
    participant Tracing as "tracing_subscriber::fmt()"
    participant DS as "DataStore::open()"
    participant Endpoint as "ServiceEndpoint::new()"
    participant Server as "muxio_tokio_rpc_server::Server"
    
    Main->>CLI: Parse command line
    CLI-->>Main: ServerArgs{port, path, log_level}
    
    Main->>Tracing: with_env_filter() + init()
    Note over Tracing: RUST_LOG or --log-level
    
    Main->>DS: open(data_file_path)
    DS-->>Main: Arc<DataStore>
    
    Main->>Endpoint: new(Arc<DataStore>)
    Endpoint-->>Main: ServiceEndpoint
    
    Main->>Server: bind(addr) + serve()
    Note over Server: Listen on 0.0.0.0:port
    Server->>Server: Accept WebSocket connections

Request Processing Pipeline

When a client connects and sends RPC requests, the server processes them through the Muxio RPC stack before reaching the storage engine.

Sources: experiments/simd-r-drive-ws-server/Cargo.toml:14-17 experiments/simd-r-drive-muxio-service-definition/Cargo.toml:14-16

graph LR
    Client["WebSocket Client"]
TokioTung["tokio_tungstenite::WebSocketStream"]
MuxioServer["muxio_tokio_rpc_server::Server"]
ServiceEndpoint["muxio_rpc_service_endpoint::ServiceEndpoint"]
ServiceDef["simd_r_drive_muxio_service_definition"]
DS["simd_r_drive::DataStore"]
Client -->|Binary WS frame| TokioTung
 
   TokioTung --> MuxioServer
 
   MuxioServer -->|bitcode::decode| ServiceEndpoint
 
   ServiceEndpoint -->|dispatch method| ServiceDef
 
   ServiceDef -->|DataStoreReader/Writer trait| DS
 
   DS -.->|Result<T>| ServiceDef
 
   ServiceDef -.-> ServiceEndpoint
 
   ServiceEndpoint -.->|bitcode::encode| MuxioServer
 
   MuxioServer -.-> TokioTung
 
   TokioTung -.->|Binary WS frame| Client

RPC Service Definition Integration

The server uses the simd-r-drive-muxio-service-definition crate to define the RPC interface contract. This crate acts as a shared dependency between the server (simd-r-drive-ws-server) and all clients (simd-r-drive-ws-client), ensuring type-safe communication.

graph TB
    subgraph SvcDef["simd_r_drive_muxio_service_definition"]
ServiceTrait["muxio_rpc_service::Service trait"]
RequestTypes["Request/Response structs"]
Bitcode["bitcode::Encode + Decode"]
end
    
    subgraph ServerSide["simd_r_drive_ws_server"]
Endpoint["muxio_rpc_service_endpoint::ServiceEndpoint"]
DataStoreAccess["DataStore method calls"]
end
    
    subgraph ClientSide["simd_r_drive_ws_client"]
Caller["muxio_rpc_service_caller::ServiceCaller"]
ClientAPI["Client implementation"]
end
    
 
   ServiceTrait --> Endpoint
 
   ServiceTrait --> Caller
 
   RequestTypes --> Bitcode
 
   Endpoint --> DataStoreAccess
 
   Caller --> ClientAPI

Service Definition Structure

Sources: experiments/simd-r-drive-muxio-service-definition/Cargo.toml:1-16 experiments/simd-r-drive-ws-server/Cargo.toml:14-17 experiments/simd-r-drive-ws-client/Cargo.toml:14-18

The service definition uses the bitcode crate (declared at experiments/simd-r-drive-muxio-service-definition/Cargo.toml14) for efficient binary serialization, providing compact message sizes and high throughput compared to JSON-based protocols.

Sources: experiments/simd-r-drive-muxio-service-definition/Cargo.toml:14-15


Dependency Graph

The server’s dependency structure shows clear separation between RPC transport layer, service definition, and storage engine:

Sources: experiments/simd-r-drive-ws-server/Cargo.toml:13-22

graph TD
    Server["simd_r_drive_ws_server"]
Server --> MuxioServer["muxio_tokio_rpc_server"]
Server --> MuxioService["muxio_rpc_service"]
Server --> ServiceDef["simd_r_drive_muxio_service_definition"]
Server --> DataStore["simd_r_drive"]
Server --> Tokio["tokio"]
Server --> Clap["clap"]
Server --> TracingSub["tracing_subscriber"]
Server --> Tracing["tracing"]
Server --> Indoc["indoc"]
MuxioServer --> TokioTung["tokio_tungstenite"]
MuxioServer --> Endpoint["muxio_rpc_service_endpoint"]
ServiceDef --> Bitcode["bitcode"]
ServiceDef --> MuxioService
    
 
   MuxioServer --> Tokio
 
   TokioTung --> Tokio
 
   Endpoint --> Tokio

Configuration and CLI

The server is configured via command-line arguments using the clap crate’s derive API (enabled via experiments/simd-r-drive-ws-server/Cargo.toml21). The indoc crate (experiments/simd-r-drive-ws-server/Cargo.toml22) is used for formatting multi-line help text.

Command-Line Interface

The server binary is invoked as:

ArgumentTypeDefaultDescription
--portu168080TCP port to bind WebSocket server
--pathPathBufRequiredPath to DataStore file
--log-levelString“info”Tracing log level (error/warn/info/debug/trace)

Environment Variables

The server supports the RUST_LOG environment variable through tracing-subscriber with env-filter feature (declared at experiments/simd-r-drive-ws-server/Cargo.toml19) for fine-grained logging control per module.

Sources: experiments/simd-r-drive-ws-server/Cargo.toml:19-22


Concurrency Model

The server leverages Tokio’s multi-threaded work-stealing scheduler (declared at experiments/simd-r-drive-ws-server/Cargo.toml18) to handle multiple concurrent WebSocket connections efficiently:

Each WebSocket connection runs as an independent async task spawned via tokio::spawn(), with the DataStore wrapped in Arc<DataStore> for shared access. The DataStore’s internal locking (see Concurrency and Thread Safety) ensures safe concurrent reads and serialized writes.

Sources: experiments/simd-r-drive-ws-server/Cargo.toml:14-18


Transport Protocol

The server uses binary WebSocket frames over TCP via the muxio-tokio-rpc-server transport layer (experiments/simd-r-drive-ws-server/Cargo.toml16):

PropertyValueImplementation
ProtocolWebSocket (RFC 6455)tokio-tungstenite (transitive dependency)
Message FormatBinary framesNot text frames
Serializationbitcodeexperiments/simd-r-drive-muxio-service-definition/Cargo.toml14
FramingMessage-per-frameEach RPC call is one WebSocket frame
MultiplexingMuxio RPC protocolRequest/response correlation via message IDs
Bind Address0.0.0.0:<port>Configurable via --port argument

The binary format and bitcode serialization provide significantly better performance than text-based protocols like JSON over WebSocket.

Sources: experiments/simd-r-drive-ws-server/Cargo.toml16 experiments/simd-r-drive-muxio-service-definition/Cargo.toml14


Error Handling

The server implements error handling at multiple layers:

  1. WebSocket Layer : Connection errors and protocol violations handled by tokio-tungstenite (transitive via muxio-tokio-rpc-server)
  2. RPC Layer : Serialization errors and invalid method calls handled by muxio-tokio-rpc-server (experiments/simd-r-drive-ws-server/Cargo.toml16)
  3. Service Layer : Request validation and type mismatches handled by muxio-rpc-service-endpoint
  4. Storage Layer : I/O errors and validation failures propagated from simd-r-drive::DataStore (experiments/simd-r-drive-ws-server/Cargo.toml14)
  5. Logging : All errors logged with structured context via tracing spans (experiments/simd-r-drive-ws-server/Cargo.toml20)

Errors are serialized back to clients as RPC error responses using bitcode encoding, preserving error context across the network boundary.

Sources: experiments/simd-r-drive-ws-server/Cargo.toml:14-20


Performance Characteristics

The server is designed for high-throughput operation with minimal overhead:

Sources: experiments/simd-r-drive-ws-server/Cargo.toml:14-18 experiments/simd-r-drive-muxio-service-definition/Cargo.toml14


Deployment Considerations

When deploying the WebSocket server, consider:

  1. Single DataStore Instance : The server opens one DataStore file at the path specified via --path. Multiple servers require separate files or external coordination
  2. Port Binding : Bind address is 0.0.0.0:<port> (all interfaces). Use firewall rules or reverse proxy for access control
  3. No TLS : The server does not implement TLS/WSS. Use a reverse proxy (nginx, HAProxy, Caddy) for encrypted connections
  4. Resource Limits :
    • Memory usage scales with DataStore size (memory-mapped file in virtual address space)
    • Per-connection buffers for WebSocket frames
    • Tokio runtime thread pool (default: number of CPU cores)
  5. Graceful Shutdown : Tokio runtime handles SIGTERM/SIGINT for clean connection closure
  6. Logging : Configure via RUST_LOG environment variable or --log-level argument (see [Configuration and CLI](https://github.com/jzombie/rust-simd-r-drive/blob/1665f50d/Configuration and CLI))

Sources: experiments/simd-r-drive-ws-server/Cargo.toml:1-22


Experimental Status

As indicated by its location in the experiments/ workspace directory, this server is currently experimental and subject to breaking changes. The API surface and configuration options may evolve as the Muxio RPC framework stabilizes.

Sources: experiments/simd-r-drive-ws-server/Cargo.toml2 experiments/simd-r-drive-ws-server/Cargo.toml11

Dismiss

Refresh this wiki

Enter email to refresh