Standard Library: Remote
The std::core::remote module provides transparent remote execution for Shape
functions. It handles wire protocol encoding, transport, and response decoding
automatically — letting you run functions on remote shape serve instances as
if they were local.
Import
Section titled “Import”from std::core::remote use { @remote }use std::core::remotefrom std::core::intrinsics use { HashMap, Ok, Err, Result }Import @remote explicitly when you want the bare annotation form. Use the
module namespace for low-level APIs such as remote::execute.
The @remote Annotation
Section titled “The @remote Annotation”The primary API is the @remote annotation. When applied to a function,
calling that function transparently executes it on the specified remote
server instead of locally.
Basic Usage
Section titled “Basic Usage”@remote("worker:9527")fn compute(data) { data.map(|x| x * 2)}
// Looks like a normal call — executes on worker:9527let result = compute([1, 2, 3])// result: Ok([2, 4, 6])The @remote annotation’s before hook intercepts the call and returns
{ result: result } where result is the Result value from the wire call —
Ok(value) on success, Err(message) on transport or execution failure.
How It Works
Section titled “How It Works”The @remote annotation uses Shape’s annotation system with a before hook
that short-circuits local execution:
- The caller invokes the function normally
- The
beforehook intercepts the call, serializes the function and arguments via the wire protocol, and sends them to the remoteshape servenode - The remote node reconstructs the function from content-addressed blobs, executes it, and returns the result
- The
beforehook returns the result directly — the function body never runs locally
With All Value Types
Section titled “With All Value Types”@remote works with all Shape value types as arguments and return values:
// Integer parameters (no heap allocation)@remote("127.0.0.1:9527")fn add(a, b) { a + b }assert add(10, 32) == Ok(42)
// Array parameters@remote("127.0.0.1:9527")fn first(arr) { arr[0] }assert first([10, 20, 30]) == Ok(10)
// String parameters@remote("127.0.0.1:9527")fn greet(name) { f"Hello, {name}!" }assert greet("World") == Ok("Hello, World!")
// Closures and higher-order functions@remote("127.0.0.1:9527")fn double_all(arr) { arr.map(|x| x * 2) }assert double_all([1, 2, 3]) == Ok([2, 4, 6])Foreign Functions (Python / TypeScript)
Section titled “Foreign Functions (Python / TypeScript)”@remote also works on foreign function definitions. The function is
compiled and executed on the remote server using its language runtime:
@remote("gpu-worker:9527")async fn python matrix_multiply(a: Array<Array<number>>, b: Array<Array<number>>) -> Result<Array<Array<number>>, string> { import numpy as np a_np = np.array(a) b_np = np.array(b) return (a_np @ b_np).tolist()}
let result = matrix_multiply([[1, 2], [3, 4]], [[5, 6], [7, 8]])// Executes Python on gpu-worker:9527Low-Level API
Section titled “Low-Level API”remote::execute(addr, code)
Section titled “remote::execute(addr, code)”Execute Shape source code on a remote server. The server compiles and runs the code string, returning the structured result.
let r = remote::execute("localhost:9527", "fn add(a, b) { a + b }\nadd(10, 32)")match r { Ok(result) => print(f"Value: {result["value"]}") // 42 Err(e) => print(f"Failed: {e}")}Parameters:
addr: string— Server address ashost:portcode: string— Shape source code to execute
Returns: Result<HashMap<string, _>, string> with fields value, stdout, error.
remote::ping(addr)
Section titled “remote::ping(addr)”Check connectivity and get server info.
match remote::ping("localhost:9527") { Ok(info) => print(f"Server v{info["shape_version"]}") Err(e) => print(f"Server down: {e}")}Returns: Result<HashMap<string, _>, string> with shape_version and wire_protocol.
remote::__call(addr, fn_ref, args)
Section titled “remote::__call(addr, fn_ref, args)”Low-level function call transport. This is the builtin used internally by
the @remote annotation. Serializes the function and arguments via the
wire protocol and sends them to the remote node.
fn square(x) { x * x }let result = remote::__call("localhost:9527", square, [7])// result: Ok(49)Parameters:
addr: string— Server addressfn_ref— Function reference to call remotelyargs: Array<_>— Arguments to pass
Returns: Ok(value) or Err(message).
Wire Protocol Integration
Section titled “Wire Protocol Integration”Remote calls use the same wire protocol as shape serve:
- Content-addressed blobs: Functions are identified by SHA-256 hash. Only blobs the server doesn’t have are transmitted.
- Blob negotiation: Persistent connections cache blobs, so repeated calls to the same function only transmit arguments.
- Compression: All frames are zstd-compressed when beneficial.
- Sidecar splitting: Large arguments (> 1 MB) are sent as parallel sidecar messages.
See Wire Protocol for full details.
Error Handling
Section titled “Error Handling”All remote calls return Result values:
@remote("unreachable:9527")fn work(x) { x * 2 }
match work(42) { Ok(v) => print(f"Got: {v}") Err(e) => print(f"Remote error: {e}")}Errors include transport failures (connection refused, timeout), server-side compilation errors, and runtime exceptions.
See Also
Section titled “See Also”- Execution Server —
shape servesetup and protocol - Annotations — annotation system mechanics
- Wire Protocol — framing, compression, blob negotiation
- Content-Addressed Bytecode — function identity and distribution