Skip to content

Instantly share code, notes, and snippets.

@cablehead
Last active October 19, 2026 02:29
Show Gist options
  • Select an option

  • Save cablehead/362de1e7c1a52c5093ce228e6ba5d70b to your computer and use it in GitHub Desktop.

Select an option

Save cablehead/362de1e7c1a52c5093ce228e6ba5d70b to your computer and use it in GitHub Desktop.
stardust alpha-2610171653: abi and rust sdk changes

@../stardust-alpha-2610171653 new stardust release. give me an overview of changes in the abi and in the rust sdk

changes from alpha-2610112101 to alpha-2610171653 (released 2026-10-17). releases

set_notify shipped, close to the proposal. rust subscriptions are now async only.

ABI: stardust.h

typedef void (*stardust_db_subscription_notify)(void *ctx);
uint32_t stardust_db_subscription_set_notify(
    stardust_db_subscription *sub,
    stardust_db_subscription_notify notify,
    void *ctx);
  • registration: as proposed.
    • set_notify MUST be called once, before the first next.
    • a second or late call returns INVALID_ARGUMENT.
    • any next counts as the first, including one that failed.
    • ctx may be NULL.
    • a failed call has no side effects.
  • arming: after registering, check with next(0). TIMEOUT arms one notify. changes that arrive before it fires are merged into it.
  • timing: notify can run on any thread, before the arming next(0) returns.
  • notify: must not call stardust "or run application code, directly or indirectly". the proposal only ruled out blocking and stardust calls.
  • ownership: "keep callback code and caller-owned context valid until release returns. after release returns, no callback is running or can run again." this covers ctx and the code the function pointer names.
  • release: now also waits for "admitted callbacks".
  • not proposed: in callback mode, next(0) hands query evaluation to shared workers.

Rust SDK: subscriptions

pub async fn next(&mut self) -> Result<Option<Event>>;
    // was: fn next(&self, Duration)
pub fn canceller(&self) -> Canceller;
    // Clone, may outlive the Subscription
impl Events<'_> { pub async fn next(&mut self) -> Option<Result<Event>> }
    // no longer an Iterator

this is the proposal's public api. any executor works. the main change is underneath: wakes go through one shared thread, described below.

Rust SDK: the stardust-wake thread (src/subscription_wait.rs)

stardust forbids notify from running application code. waking a task means calling its Waker, which is the executor's code and can do anything. so notify can't wake the task itself. it hands off to one thread, stardust-wake, shared by every subscription in the process.

what happens during sub.next().await:

  1. next saves the task's Waker in the subscription's Signal.
  2. next asks stardust for an event without waiting (next(0)). if one is ready, it returns it. if not, stardust arms notify and the future returns Pending. the task is parked. no thread is blocked.
  3. a commit changes the query's result. stardust calls notify.
  4. notify pushes the Signal onto a queue and returns.
  5. stardust-wake pops the Signal and calls its saved Waker.
  6. the executor polls the task. next repeats step 2 and gets the event.

step 1 comes before step 2 because notify can run as soon as step 2 arms it, even before step 2 returns. the Waker is already saved, so that wake isn't lost.

the queue:

  • has one slot per subscription, up to 1024 per cpu, reserved up front, so notify never allocates.
  • holds each Signal at most once. repeat notifies before the thread gets to it are merged.
  • when every slot is taken, subscribe fails with LOCKED. a slot is freed when the subscription and its cancellers are dropped.

the thread:

  • starts with the first subscription and exits after the last one is dropped.
  • calls wakers outside all locks and catches their panics.

ctx points at the Signal, which holds no native handle, so a callback can never drop the last owner and re-enter release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment