Files
Phoebe Goldman dcd8640543 Rust module bindings and macros for defining procedures (#3444)
# Description of Changes

This commit adds a macro attribute `#[procedure]` which applies to
functions, and various in-WASM machinery for defining, calling and
running procedures.

A simple example of a procedure, included in `modules/module-test`:

```rust
fn sleep_one_second(ctx: &mut ProcedureContext) {
    let prev_time = ctx.timestamp;
    let target = prev_time + Duration::from_secs(1);
    ctx.sleep_until(target);
    let new_time = ctx.timestamp;
    let actual_delta = new_time.duration_since(prev_time).unwrap();
    log::info!("Slept from {prev_time} to {new_time}, a total of {actual_delta:?}");
}
```

We intend eventually to make procedures be `async` functions (with the
trivial `now_or_never` executor from `future-util`), but I found that
making the types work for this was giving me a lot of trouble, and
decided to put it off in the interest of unblocking more parallelizable
work.

Host-side infrastructure for executing procedures is not included in
this commit. I have a prototype working, but cleaning it up for review
and merge will come a bit later.

One item of complexity in this PR is enabling scheduled tables to
specify either reducers or procedures, while still providing
compile-time diagnostics for ill-typed scheduled functions (as opposed
to publish-time). I had to rewrite the previous
`schedule_reducer_typecheck` into a more complex `schedule_typecheck`
with a trait `ExportFunctionForScheduledTable`, which takes a "tacit
trait parameter" encoding reducer-ness or procedure-ness, as described
in https://willcrichton.net/notes/defeating-coherence-rust/ .

The trait name `ExportFunctionForScheduledTable` is user-facing in the
sense that it will appear in compiler diagnostics in ill-typed modules.
As such, I am open to bikeshedding.

# API and ABI breaking changes

Adds a new user-facing API, which we intend to change before releasing.

# Expected complexity level and risk

2? Mostly pretty mechanical changes to macros and bindings.

# Testing

- [x] Added a procedure definition to `module-test`, saw that it
typechecks.
- [x] Executed same procedure definition using #3390 , the prototype
implementation this PR draws from.
2025-10-24 14:35:32 +00:00
..
2025-08-22 19:36:47 +00:00

module-test Rust test

Called as part of our integration tests to ensure the system is working as expected.

Note: Also mirrored as a C# version at modules/module-test-cs, so must be kept in sync.

How to Run

Execute individual tests with module-test for Rust and module-test-cs for C# at standalone_integration_test, or call

# Will run both Rust/C# module
cargo test -p spacetimedb-testing
# Only Rust
cargo test -p spacetimedb-testing rust
# Only C#
cargo test -p spacetimedb-testing csharp