Welcome to the new Golem Cloud Docs! 👋
Documentation
WASM RPC

WASM-RPC

⚠️

Prefer the typed approaches to worker-invocation explained in the introduction. This section describes the underlying interfaces that are used by golem itself to implement the typed approaches to RPC.

The low-level interface to invoke other workers from within a component is the WASM-RPC (opens in a new tab) wit package. The basic workflow of using this package is to construct an instance of the wasm-rpc resource (which represents a remote worker) and call the appropriate method on it.

Constructing an instance

The only argument required to construct an wasm-rpc resource is the URI of the worker you wish to invoke. The structure of this URI is urn:worker:{component_id}/{worker_name}. Both component_id and worker_name are given to you by golem when you create a component and worker respectively.

WIT-Value

As the wasm-rpc package is not statically typed, it is required to be able to pass as arguments and return arbitrary WIT values. This is done using the WIT-Value datatype which is a reified version of the regular WIT types. There is one constructor of the related WIT-Node type for each type in the WIT typesystem, i.e. a list<u64> with value [1, 2, 4] might be represented like this in a rust component using wasm-rpc:

WitValue {
      nodes: vec![WitNode::ListValue(vec![1, 2, 3]), WitNode::PrimU64(1), WitNode::PrimU64(2), WitNode::PrimU64(4)]
}

The value that will end up becoming the root of the resulting WIT Value needs to be placed in index 0 of the nodes array!

All functions in the wasm-rpc package use wit-value instead of the equivalent wit type. Invoking a function with incorrect wit-values with lead to an error.

Invocation

After you have constructed an instance of wasm-rpc there are a number of different functions you can choose from, depending on the invocation semantics you need.

  • invoke: Non-blockingly call the desired function. Errors during invocation are returned, but the actual result of the invocation cannot be accessed.
  • invoke-and-await: Blockingly call the desired function. The result of the invocation will be returned to you.
  • async-invoke-and-await: Non-blockingly call the desired function. A resource will be returned to you that you can use to poll the result.
  • schedule-invocation: Schedule an invocation for a point in time in the future.
  • schedule-cancelable-invocation: Schedule an invocation for a point in time in the future. A resource will be returned to you that you can cancel the invocation as long as it hasn't been executed yet.

Example

Given the following WIT world implemented by a component:

package golem:example;
 
interface invocation-example-api {
  add: func(value: u64);
}
 
world invocation-example {
  export invocation-example-api;
}

A rust component could use the wasm-rpc package to schedule an invocation of 'add' 2 seconds in the future like this:

let uri = Uri { value: format!("urn:worker:{}/{}", component_id, worker_name) }
 
let wasi_rpc = WasmRpc::new(&uri);
 
let now = OffsetDateTime::now_utc();
 
let scheduled_time = now.saturating_add(Duration::seconds(2));
 
let scheduled_wasi_time = WasiDatetime {
   seconds: scheduled_time.unix_timestamp() as u64,
   nanoseconds: scheduled_time.nanosecond()
};
 
let value: WitValue = {
   use self::bindings::golem::rpc::types::*;
   WitValue {
         nodes: vec![WitNode::PrimU64(1)]
   }
};
wasi_rpc.schedule_invocation(scheduled_wasi_time, "golem:example/invocation-example-api.{add}()", &vec![value]);