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

The simd-r-drive-ws-server is an experimental RPC wrapper around the core DataStore engine. It enables remote access to the append-only storage via a multiplexed WebSocket transport, leveraging the muxio framework for high-concurrency request/response handling.

Overview and Architecture

The server acts as a bridge between the physical storage on disk and remote clients. It encapsulates a DataStore instance within an Arc<RwLock<DataStore>> to allow safe, concurrent access across multiple asynchronous WebSocket connections handled by tokio experiments/simd-r-drive-ws-server/src/main.rs:31-39

Request Lifecycle

  1. Transport : The server initializes an RpcServer which manages the underlying WebSocket transport experiments/simd-r-drive-ws-server/src/main.rs:42-43
  2. Multiplexing : The muxio protocol allows multiple concurrent RPC calls over a single WebSocket connection without head-of-line blocking.
  3. Dispatch : The RpcServiceEndpointInterface receives a frame, identifies the METHOD_ID, and dispatches it to the registered prebuffered handler experiments/simd-r-drive-ws-server/src/main.rs:55-57
  4. Execution : Handlers use task::spawn_blocking to move heavy I/O and locking operations off the async executor experiments/simd-r-drive-ws-server/src/main.rs:60-67 They acquire a read or write lock on the DataStore (e.g., blocking_write or blocking_read) and execute the corresponding operation experiments/simd-r-drive-ws-server/src/main.rs:62-63
  5. Response : Results are serialized using bitcode (via the service definition) and sent back through the multiplexer experiments/simd-r-drive-ws-server/src/main.rs:64-65

Data Flow Diagram

The following diagram illustrates how the server wraps the core library and exposes it over the network.

WebSocket Server Data Flow

graph TD
    subgraph "NetworkLayer"
        "RemoteClient" -- "WebSocket (muxio)" --> "RpcServer[muxio-tokio-rpc-server]"
    end

    subgraph "ServerProcess(simd-r-drive-ws-server)"
        "RpcServer" -- "Dispatch" --> "Endpoint[RpcServiceEndpointInterface]"
        "Endpoint" -- "spawn_blocking" --> "Handlers[RPC Handlers]"
        "Handlers" -- "blocking_write()" --> "SharedStore[Arc<RwLock<DataStore>>]"
        "Handlers" -- "blocking_read()" --> "SharedStore"
        
        subgraph "CoreEngine"
            "SharedStore" -- "I/O" --> "DataStore[simd_r_drive::DataStore]"
        end
    end

    subgraph "Storage"
        "DataStore" -- "Append/Mmap" --> "StorageFile[.bin]"
    end

Sources: experiments/simd-r-drive-ws-server/src/main.rs:36-67 experiments/simd-r-drive-ws-server/src/cli/cli_parser.rs:16-42

RPC Endpoints and Service Registration

The server registers a suite of endpoints that mirror the DataStoreReader and DataStoreWriter traits experiments/simd-r-drive-ws-server/src/main.rs:55-163 These are defined in the simd-r-drive-muxio-service-definition crate to ensure type safety between the server and the client.

EndpointMethod IDImplementation Detail
writeWrite::METHOD_IDCalls store.write(&params.key, &params.payload) experiments/simd-r-drive-ws-server/src/main.rs63
batch_writeBatchWrite::METHOD_IDIterates and calls store.batch_write(&borrowed_entries) experiments/simd-r-drive-ws-server/src/main.rs86
readRead::METHOD_IDCalls store.read(&params.key) and returns Vec<u8> experiments/simd-r-drive-ws-server/src/main.rs:104-106
batch_readBatchRead::METHOD_IDCalls store.batch_read(&key_refs) experiments/simd-r-drive-ws-server/src/main.rs126
deleteDelete::METHOD_IDAppends a tombstone via store.delete(&params.key) experiments/simd-r-drive-ws-server/src/main.rs154
lenLen::METHOD_IDReturns store.len() experiments/simd-r-drive-ws-server/src/main.rs172
is_emptyIsEmpty::METHOD_IDReturns store.is_empty() experiments/simd-r-drive-ws-server/src/main.rs189
file_sizeFileSize::METHOD_IDReturns store.file_size() experiments/simd-r-drive-ws-server/src/main.rs206
existsExists::METHOD_IDReturns store.exists(&params.key) experiments/simd-r-drive-ws-server/src/main.rs223

Code Entity Mapping

Sources: experiments/simd-r-drive-ws-server/src/main.rs:14-19 experiments/simd-r-drive-ws-server/src/main.rs:55-163 experiments/simd-r-drive-ws-server/src/main.rs:172-223

CLI Configuration

The server is started via a CLI that configures the storage path and network binding. The CLI is built using clap experiments/simd-r-drive-ws-server/src/cli/cli_parser.rs:8-16

Arguments and Flags

Error Handling

The CLI includes a custom error handler in Cli::parse_args() that detects MissingRequiredArgument errors and displays a detailed help template instead of a generic error message experiments/simd-r-drive-ws-server/src/cli/cli_parser.rs:45-61

Sources: experiments/simd-r-drive-ws-server/src/cli/cli_parser.rs:1-62 experiments/simd-r-drive-ws-server/src/cli/help_template.rs:4-14

Implementation Details

Concurrency Model

The server uses a multi-layered concurrency approach:

  1. Outer Lock : An Arc<RwLock<DataStore>> protects the DataStore instance across multiple tokio tasks experiments/simd-r-drive-ws-server/src/main.rs:36-39
  2. Blocking Tasks : Because DataStore operations involve synchronous file I/O and CPU-intensive SIMD/hashing, handlers use task::spawn_blocking to prevent blocking the tokio worker threads experiments/simd-r-drive-ws-server/src/main.rs:60-67
  3. Read/Write Separation : Handlers use blocking_read() for operations like read, len, and exists to allow parallel read access, while using blocking_write() for write and delete to ensure exclusive access during appends experiments/simd-r-drive-ws-server/src/main.rs62 experiments/simd-r-drive-ws-server/src/main.rs103

Serialization

Request and response parameters are serialized using bitcode. The server decodes incoming requests (e.g., Write::decode_request(&bytes)) and encodes outgoing responses (e.g., Write::encode_response(...)) using methods provided by the RpcMethodPrebuffered trait implementation experiments/simd-r-drive-ws-server/src/main.rs:61-65

Sources: experiments/simd-r-drive-ws-server/src/main.rs:31-40 experiments/simd-r-drive-ws-server/src/main.rs:55-115