Skip to content

Conversation

@gefjon
Copy link
Contributor

@gefjon gefjon commented Oct 21, 2025

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:

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

  • Added a procedure definition to module-test, saw that it typechecks.
  • Executed same procedure definition using Phoebe/procedures #3390 , the prototype implementation this PR draws from.

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.
@gefjon gefjon requested a review from Centril October 21, 2025 16:51
@gefjon
Copy link
Contributor Author

gefjon commented Oct 22, 2025

Test failures are coming from two places, AFAICT:

  1. Adding a procedure to module-test breaks ensure_same_schema. I will have to remove the example before merging.
  2. The trait ExportFunction is under-constrained, causing scheduled_function_typecheck to pass unconditionally.

1 is easy enough, but 2 is challenging. Rust seems to not like implementing traits for specific function types, and is not smart enough to recognize that Fn(&ReducerContext, ...) is disjoint from Fn(&mut ProcedureContext, ...) (or maybe it isn't. Can you implement Fn manually?). As such I've been unable to come up with an incantation where ExportFunction gets impled for every valid reducer or procedure function type but not for any other types.

@gefjon
Copy link
Contributor Author

gefjon commented Oct 23, 2025

I have fixed the bug I listed above as 2! I will update the PR description with a note.

@gefjon
Copy link
Contributor Author

gefjon commented Oct 23, 2025

Looks like I was wrong about the ensure_same_schema checks, actually - those don't seem to care about reducers and procedures.

Turns out I can't type/spell
Copy link
Collaborator

@joshua-spacetime joshua-spacetime left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving, pending a doc comment for the macro.

These are quite bare-bones, as much of the stuff we'd want to document isn't implemented yet.
@gefjon gefjon enabled auto-merge October 24, 2025 13:15
@gefjon gefjon disabled auto-merge October 24, 2025 13:28
@gefjon gefjon enabled auto-merge October 24, 2025 14:34
@gefjon gefjon added this pull request to the merge queue Oct 24, 2025
Merged via the queue into master with commit dcd8640 Oct 24, 2025
25 of 26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants