-
Notifications
You must be signed in to change notification settings - Fork 685
Implement event tables #4217
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
cloutiertyler
wants to merge
16
commits into
phoebe/rust-sdk-ws-v2
Choose a base branch
from
tyler/impl-event-tables
base: phoebe/rust-sdk-ws-v2
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Implement event tables #4217
+2,839
−200
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
c96550a to
57cc9a5
Compare
cloutiertyler
commented
Feb 6, 2026
c13a4b1 to
07d57a5
Compare
gefjon
reviewed
Feb 9, 2026
Contributor
|
A few things:
|
2ddac79 to
614401f
Compare
Each validated schema type (TableDef, IndexDef, ReducerDef, etc.) now has its own From impl for the corresponding V10 raw type, mirroring the existing V9 conversions. The main From<ModuleDef> for RawModuleDefV10 is simplified to use .into() calls.
- Split Table trait: independent EventTable (insert-only) and Table (insert + delete) traits in the Rust client SDK - Codegen generates EventTable impl for event tables, Table impl for persistent tables; skips TableWithPrimaryKey, unique accessors, and cache diff for event tables - Event table inserts fire on_insert callbacks without persisting to the client cache via into_event_diff() - Filter event tables from V1 SELECT * FROM * subscriptions - Reject event tables as lookup table in subscription semi-joins - Disallow event tables in view definitions - Switch extract_schema to V10 output format - Regenerate test client bindings with V10 codegen
…t tables - Add sdk-test-event-table module and event-table-client test harness - Add three integration tests: basic event table, multiple events in one reducer, and events-don't-persist-across-transactions - Add compile-time tests for CanBeLookupTable enforcement on event tables - Add returns_event_table() to SubscriptionPlan and Plan - Reject v1 WebSocket subscriptions to event tables with a clear error message directing developers to upgrade to v2
- Add exec_v1_rejects_event_table test verifying v1 clients get a clear error when subscribing to event tables - Mark the 3 event table integration tests as #[ignore] since they require v2 WebSocket support in the Rust SDK (not yet implemented) - Add docs/event-tables-status.md tracking what's implemented vs remaining from the event tables proposal
The client can synthesize on_delete from the insert since every event table row is a noop. Implementers may defer on_delete generation.
- Replace on_<reducer>() callbacks with _then() invocation pattern - Replace Status::Failed/OutOfEnergy with Status::Err/Panic - Remove CallReducerFlags, set_reducer_flags, Event::UnknownTransaction - Remove ReducerEvent.caller_identity/caller_connection_id field access - Use noop_then() instead of on_noop() in event-table-client
- Pass the generated request_id into CallReducer message instead of hardcoded 0, matching the procedure code pattern - Remove #[ignore] from event table tests now that SDK uses v2 - Remove v1_rejects_event_table test (SDK no longer uses v1)
Move completed items (v2 subscription path, Rust SDK v2, reducer callback deprecation, active integration tests) from "Not Yet Implemented" to "Implemented". Add "Deferred" section for well-defined but postponed work (on_delete codegen, joins, views). Add "Known Issues" section documenting v2 test stability and the fixed request_id bug. Fix proposal link path.
614401f to
ea81292
Compare
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description of Changes
Adds event tables support to SpacetimeDB (Rust server bindings only, V10 ABI).
Event tables are write-only tables whose rows persist to the commitlog but are NOT merged into committed state. Their rows are ephemeral in memory — only visible to V2 subscribers in the transaction that inserted them.
Schema & ABI:
is_event: booltoRawTableDefV10,TableDef, andTableSchemast_event_tablesystem table (TableId 17) tracks which tables are event tables, avoiding migration ofStTableRowis_eventis reconstructed fromst_event_tableinschema_for_table_raw()Rust bindings macro:
eventkeyword:#[spacetimedb::table(name = my_events, public, event)]const IS_EVENT: bool = true;onTableInternalregister_table()to V10 builder's.with_event()Core behavior:
merge_apply_inserts(): event table rows are recorded in TxData (for commitlog + subscriptions) but skip merging into committed statereplay_insert(): event table rows return early — no committed state rebuilt on restartCompile-time semi-join validation:
CanBeLookupTablemarker trait inquery-builder— event tables don't implement itR: CanBeLookupTable, giving a compile error if an event table is used as the lookup sideCherry-picks
joshua/shub/raw-module-def-v10(#4153) as a prerequisite. V9 is completely untouched.Deferred: V2 subscription evaluation, runtime SQL semi-join validation, view validation.
API and ABI breaking changes
New field
is_event: booladded toRawTableDefV10(appended at end for ABI compat). Defaults tofalse, so existing modules are unaffected.CanBeLookupTabletrait bound replacesHasIxColson semi-join methods in the query builder. All non-event tables implementCanBeLookupTable, so existing code compiles unchanged.Expected complexity level and risk
3 — The changes touch the schema pipeline end-to-end (raw def → validated def → runtime schema → system table → committed state merge/replay), but each individual change is straightforward. The main risk area is the merge skip logic in
committed_state.rs, which is on the hot path and must correctly distinguish event tables from persistent ones. The system table approach avoids any migration risk for existing databases.Testing
cargo checkpasses (verified locally)