Skip to content

Async Inter-database Communication (Async IDC) #5198

Description

@website-features

I would like to be able to send messages from one database to another via an outbox table.

Sender side (inventory module)

  1. Declare the outbox table. It needs a #[primary_key] #[auto_inc] u64 msg_id, a #[target] typed identity, and payload columns matched by name to the receiver reducer's parameters.
  use game_world as gw;

  #[spacetimedb::table(name = out_receive_item, outbox(gw::receive_item))]
  pub struct OutReceiveItem {
      #[primary_key]
      #[auto_inc]
      msg_id: u64,            // runtime-assigned sequence number

      #[target]
      target: gw::Identity,   // which database to deliver to

      // Payload columns — names must match gw::receive_item's parameters.
      item_id: u64,
      qty: u32,
  }

Defaults are the strong guarantees: ordered = true, reliable = true → ordered, exactly-once delivery per (sender, receiver).

  1. Send by inserting a row. Leave msg_id at 0; the runtime assigns it on commit. If the transaction rolls back, nothing is sent.
  #[spacetimedb::reducer]
  fn transfer_item(ctx: &ReducerContext, to: gw::Identity, item_id: u64, qty: u32) {
      ctx.db.out_receive_item().insert(OutReceiveItem {
          msg_id: 0,
          target: to,
          item_id,
          qty,
      });
  }
  1. (Optional) Observe the outcome. Attach an on_result reactive reducer naming the outbox table. It fires once per terminated delivery, post-commit, on the sender. Ok(()) means the
    receiver returned Ok; Err(s) carries the receiver's error or a terminal transport/schema failure.
  #[spacetimedb::reducer(on_result(out_receive_item))]
  fn on_transfer_result(
      ctx: &ReducerContext,
      row: OutReceiveItem,
      result: Result<(), String>,
  ) {
      if let Err(err) = result {
          log::warn!("transfer of item {} to {:?} failed: {}", row.item_id, row.target, err);
      }
  }

Requested by @cloutiertyler via the SpacetimeDB site.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions