Stub Activities

Activities with no real implementation except for their WIT exports and configured in [[activity_stub]] table are called Stub Activities.

Stub activity functions are not executed by the Obelisk runtime. Instead, the following steps are executed:

  1. The parent workflow calls the stub function. Both direct calls (e.g. myactivity()) and async counterparts (e.g. myactivity_submit) are supported.
  2. An external process or workflow injects the execution result by supplying a return value or an execution error for the given Execution ID.
  3. The parent execution obtains the return value and continues its logic.

The parent execution is agnostic of whether the child activity is a regular WASM activity or a stub activity.

Consider two activity functions defined in WIT like this:

package testing:stub-activity;

interface activity {
    foo: func(arg: string) -> string;

    noret: func();
}

Obelisk automatically generates -obelisk-stub extension interface for each WIT export. The -stub function takes the Execution ID and the return value an execution error. The -obelisk-stub interface can only be imported by workflows.

package testing:stub-activity-obelisk-stub;

interface activity {
    use obelisk:types/execution@4.2.0.{execution-id, stub-error};

    foo-stub: func(execution-id: execution-id, return-value: string) -> result<_, stub-error>;

    noret-stub: func(execution-id: execution-id) -> result<_, stub-error>;

}

The return value can also be injected using Web UI or CLI.

The stubbed response call is idempotent, meaning it can be executed multiple times as long as the response remains the same. Otherwise an stub-error is returned:

variant stub-error {
    /// Conflict can happen when a second writer attempts to stub a value, while the
    /// value is not equal to the already stubbed value.
    conflict,
}

An example stub workflow is available in the repository.