mirror of
https://github.com/clockworklabs/SpacetimeDB.git
synced 2026-07-25 11:32:30 -04:00
bot/sql-format-option
31 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
fc47257d85 |
Use SpacetimeDBGuard for SDK test suite (#5340)
# Description of Changes Use an isolated server process per SDK test instead of a single process for all of the tests. In addition to reducing the memory footprint of each test run, this should also allow for more parallelism among the individual tests. # API and ABI breaking changes None # Expected complexity level and risk 1.5 # Testing The SDK test suite should continue to work |
||
|
|
10a4779b13 |
wasm support for Rust SDK (#4183)
# Description of Changes This PR adapts the Rust SDK test suite to work with the wasm version added in https://github.com/clockworklabs/SpacetimeDB/pull/4089 (which I've closed in favor of this PR). Most of the changes revolve around wasm's different async semantics - everything runs in one thread, so things that relied on background threads didn't work directly. Several tests would lock up because something in them blocked synchronously, which blocked any background work from progressing. We moved the test-clients contents into a `test_handlers.rs` so that it could be called from both `main` (for native tests) and `lib` (for wasm tests). To show what actually changed, use: ```bash git diff --no-index -- <(git show origin/master:sdks/rust/tests/procedure-client/src/main.rs) sdks/rust/tests/procedure-client/src/test_handlers.rs ``` (or similar for other test-clients) # API and ABI breaking changes None, I think/hope. # Expected complexity level and risk 2 # Testing - [x] I've augmented the CI to also run the test suite with the `web` feature --------- Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com> Co-authored-by: Thales R <thlsrmsdev@gmail.com> Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com> |
||
|
|
6882232108 |
Add a mode to the Rust SDK with additional logging to a file (#4566)
# Description of Changes
In the Rust client SDK, with this PR, doing
`.with_debug_to_file("path.txt")` on the connection builder will result
in the SDK logging additional verbose info to `path.txt`.
# API and ABI breaking changes
Adds a new user-facing-ish API to the Rust client SDK.
# Expected complexity level and risk
2? Some possibility of deadlock due to adding a new mutex, but this is
explicitly not for production use.
# Testing
- [x] Ran `chat-console-rs` locally with this enabled and got some debug
logs out of it.
|
||
|
|
e2f8a60759 |
Case conversion (#4263)
# Description of Changes Update the Default casing policy to `snake_case` for `RawModuleDefV10`. Messy PR contains changes at different places, so that CI can pass: Here are the main changes as follows: - `bindings-macro` & `bindings` crate: `name` macro in Indexes for canonical name and supply it to `RawModuleDefV10` via `ExplicitNames`. - `bindings-typescript`: - Changes has been reviewed through this PR - https://github.com/clockworklabs/SpacetimeDB/pull/4308. - `binding-csharp`: a single line change to pass `sourceName` of index instead of null. - `codegen`: - Changes has been merged from branch - https://github.com/clockworklabs/SpacetimeDB/pull/4337. - Except a fix in rust codegen to use canonical name in Query buillder instead of accessor. - `lib/db/raw_def`: Extends `RawDefModuleV10` structure to support case conversion. - `schema` crate: - `validate/v9` - Nothing itself should change or changes in v9 validation logic but the file contains a `CoreValidator` which is shared with `validate/v10`. No test have t be updated to `validate/v9` which ensures we aren't regressing it. - `validate/v10`: This is the main meat, look at the new tests added in bottom to understand what it does. - Rest of the files are either test updates or module bindings. ## Testing: 1. Extensive unit tests have been added to verify generated `ModuleDef` is correct. 2. I have done some e2e testing to verify rust codegen with rust and typescript modules. 3. I would have like to do more testing for other codegens , I am continue doing . I have removed `sql.py` smoketest, as that seems to be already migated in new framework and was headache to update. ## Expected complexity level and risk 4, It could have side-effect which aren't easily visible. - - - --------- Signed-off-by: Shubham Mishra <shivam828787@gmail.com> Co-authored-by: rekhoff <r.ekhoff@clockworklabs.io> Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com> Co-authored-by: clockwork-labs-bot <bot@clockworklabs.com> Co-authored-by: joshua-spacetime <josh@clockworklabs.io> Co-authored-by: Noa <coolreader18@gmail.com> Co-authored-by: = <cloutiertyler@gmail.com> Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@clockworklabs.io> Co-authored-by: Jason Larabie <jason@clockworklabs.io> Co-authored-by: Phoebe Goldman <phoebe@clockworklabs.io> |
||
|
|
2c8f62e019 |
Make Rust test clients listen for reducer errors (#4359)
# Description of Changes Prior to this commit, if a reducer call failed during a test in the Rust SDK test suite, the client would hang, as it generally didn't register callbacks when invoking reducers. This could mask some bugs, causing the tests to fail with TIMEOUT rather than a useful message. For example, we relied on consistency between all of the test modules, which was broken by our not having updated the C++ bindings library to use the new case-conversion scheme. This meant that the client was sending reducer calls with incorrect reducer names to at least one database per test run, which would result in a `Panic` status or an `Err(Err(_))` outcome. With this commit, the SDK test clients are updated to inspect the exit status of reducers they invoke, and (except for intentional reducer failures) to panic the test client when encountering a reducer error or panic. # API and ABI breaking changes N/a # Expected complexity level and risk 1 # Testing - [x] Automated tests passed locally. - [x] Intentionally broke reducer calls via the 2.0 WS API, causing them to skip the call and unconditionally respond with `Status::Panic`. Observed "loud" failures in the test suite with non-`TIMEOUT` output that looked more debuggable to me. |
||
|
|
4c962b9170 |
spacetime.json config implementation (#4199)
# Description of Changes
This PR implements support for the `spacetime.json` configuration file
that can be used to set up common `generate` and `publish` targets. An
example of `spacetime.json` could look like this:
```
{
"dev_run": "pnpm dev",
"generate": [
{ "out-dir": "./foobar", "module-path": "region-module", "language": "c-sharp" },
{ "out-dir": "./global", "module-path": "global-module", "language": "c-sharp" },
],
"publish": {
"database": "bitcraft",
"module-path": "spacetimedb",
"server": "local",
"children": [
{ "database": "region-1", "module-path": "region-module", server: "local" },
{ "database": "region-2", "module-path": "region-module", server: "local" }
]
}
}
```
With this config, running `spacetime generate` without any arguments
would generate bindings for two targets: `region-module` and
`global-module`. `spacetime publish` without any arguments would publish
three modules, starting from the parent: `bitcraft`, `region-1`, and
`region-2`. On top of that, the command `pnpm dev` would be executed
when using `spacetime dev`.
It is also possible to pass additional command line arguments when
calling the `publish` and `generate` commands, but there are certain
limitations. There is a special case when passing either a module path
to generate or a module name to publish. Doing that will filter out
entries in the config file that do not match. For example, running:
```
spacetime generate --project-path global-module
```
would only generate bindings for the second entry in the `generate`
list.
In a similar fashion, running:
```
spacetime publish region-1
```
would only publish the child database with the name `region-1`
Passing other existing arguments is also possible, but not all of the
arguments are available for multiple configs. For example, when running
`spacetime publish --server maincloud`, the publish command would be
applied to all of the modules listed in the config file, but the
`server` value from the command line arguments would take precedence.
Running with arguments like `--bin-path` would, however, would throw an
error as `--bin-path` makes sense only in a context of a specific
module, thus this wouldn't work: `spacetime publish --bin-path
spacetimedb/target/debug/bitcraft.wasm`. I will throw an error unless
there is only one entry to process, thus `spacetime publish --bin-path
spacetimedb/target/debug/bitcraft.wasm bitcraft` would work, as it
filters the publish targets to one entry.
# API and ABI breaking changes
None
# Expected complexity level and risk
3
The config file in itself is not overly complex, but when coupled with
the CLI it is somewhat tricky to get right. There are also some changes
that I had to make to how clap arguments are validated - because the
values can now come from both the config file and the clap config, we
can't use some of the built-in validations like `required`, or at least
I haven't found a clean way to do so.
# Testing
I've added some automated tests, but more tests and manual testing is
coming.
---------
Signed-off-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
Co-authored-by: bradleyshep <148254416+bradleyshep@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: = <cloutiertyler@gmail.com>
Co-authored-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
|
||
|
|
3f58b5951b |
Implement event tables (server, Rust/TS/C# codegen + client SDKs) (#4217)
## Summary
Implements event tables end-to-end: server datastore, module bindings
(Rust/TypeScript/C#), client codegen (Rust/TypeScript/C#), client SDKs
(Rust/TypeScript/C#), and integration tests.
Event tables are tables whose rows are ephemeral — they persist to the
commitlog and are delivered to V2 subscribers, but are NOT merged into
committed state. Rows are only visible within the transaction that
inserted them. This is the mechanism that replaces reducer event
callbacks in 2.0.
## What's included
### Server
- `is_event` flag on `RawTableDefV10`, `TableDef`, `TableSchema`
- Event table rows recorded in TxData but skipped during committed state
merge
- Commitlog replay treats event table inserts as no-ops
- Migration validation rejects changing `is_event` between module
versions
- `SELECT * FROM *` excludes event tables
- V1 WebSocket subscriptions to event tables rejected with upgrade
message
- V2 subscription path delivers event table rows correctly
- `CanBeLookupTable` trait — event tables cannot be lookup tables in
semijoins
- Runtime view validation rejects event tables
### Module bindings
- **Rust**: `#[spacetimedb::table(name = my_events, public, event)]`
- **TypeScript**: `table({ event: true }, ...)`
- **C#**: `[Table(Event = true)]`
### Client codegen (`crates/codegen/`)
- **Rust**: Generates `EventTable` impl (insert-only) for event tables,
`Table` impl for normal tables. `CanBeLookupTable` emitted for non-event
tables.
- **TypeScript**: Emits `event: true` in generated table schemas.
`ClientTableCore` type excludes `onDelete`/`onUpdate` for event tables
via conditional types.
- **C#**: Generates classes inheriting from `RemoteEventTableHandle`
(which hides `OnDelete`/`OnBeforeDelete`/`OnUpdate`) for event tables.
### Client SDKs
- **Rust**: `EventTable` trait with insert-only callbacks, client cache
bypass, `count()` returns 0, `iter()` returns empty
- **TypeScript**: Event table cache bypass in `table_cache.ts` — fires
`onInsert` callbacks but doesn't store rows. Type-level narrowing
excludes delete/update methods.
- **C#**: `RemoteEventTableHandle` base class hides delete/update
events. Parse/Apply/PostApply handle `EventTableRows` wire format, skip
cache storage, fire only `OnInsert`.
### Tests
- 9 datastore unit tests (insert/delete/update semantics, replay,
constraints, indexes, auto-inc, cross-tx reset)
- 3 Rust SDK integration tests (basic events, multiple events per
reducer, no persistence across transactions)
- Codegen snapshot tests (Rust, TypeScript, C#)
- Trybuild compile tests (event tables rejected as semijoin lookup
tables)
## Deferred
- `on_delete` codegen for event tables (server only sends inserts;
client synthesis deferred)
- Event tables in subscription joins / views (well-defined but
restricted for now)
- C++ SDK support
- RLS integration test
## API and ABI breaking changes
- `is_event: bool` added to `RawTableDefV10` (appended, defaults to
`false` — existing modules unaffected)
- `CanBeLookupTable` trait bound on semijoin methods in query builder
(all non-event tables implement it, so existing code compiles unchanged)
- `RemoteEventTableHandle` added to C# SDK (new base class for generated
event table handles)
## Expected complexity level and risk
3 — Changes touch the schema pipeline end-to-end and all three client
SDKs, but each individual change is straightforward. The core risk area
is the committed state merge skip in `committed_state.rs`. Client SDK
changes are additive (new code paths for event tables, existing paths
unchanged).
## Testing
- [x] `cargo clippy --workspace --tests --benches` passes
- [x] `cargo test -p spacetimedb-codegen` (snapshot tests)
- [x] `cargo test -p spacetimedb-datastore --features
spacetimedb-schema/test -- event_table` (9 unit tests)
- [x] `pnpm format` passes
- [x] Rust SDK integration tests pass (`event_table_tests` module)
---------
Signed-off-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
Co-authored-by: Phoebe Goldman <phoebe@goldman-tribe.org>
Co-authored-by: Jason Larabie <jason@clockworklabs.io>
Co-authored-by: joshua-spacetime <josh@clockworklabs.io>
|
||
|
|
1592dec8af |
Update Rust client SDK for V2 WebSocket format (#4257)
# Description of Changes
Update the Rust client SDK to use the new V2 WebSocket format, and
present the V2 user-facing API.
## Reducer events
### Remove on-reducer callbacks
It's no longer possible to observe reducers called by other clients by
registering callbacks with `ctx.reducers.on_{my_reducer}`. We no longer
code-generate those methods, or the associated
`ctx.reducers.remove_on_{my_reducer}`. Internal plumbing for storing and
invoking those callbacks is also removed.
### Add specific reducer invocation callbacks
In addition to the previous way to invoke reducers,
`ctx.reducers.{my_reducer}(args...)`, we add a method that registers a
callback to run after the reducer is finished. This method has the
suffix `_then`, as in `ctx.reducers.{my_reducer}_then(args...,
callback)`.
The callback will accept two arguments:
- `ctx: &ReducerEventContext`, the same context as was previously passed
to on-reducer callbacks.
- `status: Result<Result<(), String>, InternalError>`, denoting the
outcome of the reducer.
- `Ok(Ok(())` means the reducer committed. This corresponds to
`ReducerOutcome::Ok` or `ReducerOutcome::Okmpty` in the new WS format.
- `Ok(Err(message))` means the reducer returned an "expected" or "user"
error. This corresponds to `ReducerOutcome::Err` in the new WS format.
- `Err(internal_error)` means something went wrong with host execution.
This corresponds to `ReducerOutcome::InternalError` in the new WS
format.
Internally, the SDK stores the callbacks in its `ReducerCallbacks` map.
This is keyed on `request_id: u32`, a number that is generated for each
reducer call (from an `AtomicU32` that we increment each time), and
included in the `ClientMessage::CallReducer` request. The
`ServerMessage::ReducerResult` includes the same `request_id`, so the
SDK pops out of the `ReducerCallbacks` and invokes the appropriate
callback when processing that message.
These new callbacks are very similar to the existing procedure
callbacks.
### The `Event` exposed to row callbacks
Row callbacks caused by a reducer invoked by this client will see
`Event::Reducer`, the same as they would prior to this PR. These
callbacks will be the result of a `ServerMessage::ReducerResult` with
`ReducerOutcome::Ok`. In order to expose the reducer name and arguments
to this event, the client stores them in its `ReducerCallbacks` map,
alongside the callback for when the reducer is complete.
Row callbacks caused by any other reducer, or any non-reducer
transaction, are now indistinguishable to the client. These will see
`Event::Transaction`, which is renamed from the old
`Event::UnknownTransaction`.
### Less metadata in `ReducerEvent`
Some metadata is removed from `ReducerEvent`, as the V2 WebSocket format
no longer publishes it, even to the caller.
## `CallReducerFlags` are removed
All machinery for setting, storing and applying call reducer flags is
removed from the SDK, as the new WS format does not have any non-default
flags.
## Requesting rows in unsubscribe
When sending a `ClientMessage::Unsubscribe`, we always request that the
server include the matching rows in its response
`ServerMessage::UnsubscribeApplied`. This saves us having to update the
SDK to store query sets separately, at least for now. (We'll do that
later.)
## Handling rows
The new SDK does some additional parsing to wrangle rows in the new
WebSocket format into the same internal data structures as before,
rather than re-writing the client cache. (We'll do that later.)
Specifically, parsing of `DbUpdate` is changed so that:
- We parse raw `TransactionUpdate` into the generated `DbUpdate` type,
which requires an additional loop compared to the previous version, to
cope with the new WS format's dividing updates by query set. We define a
function `transaction_update_iter_table_updates` which encapsulates this
nested loop in an iterator.
- We have two new functions for parsing raw `QueryRows` into the
generated `DbUpdate` type, one for when they come from a
`SubscribeApplied`, and the other when they come from an
`UnsubscribeApplied`. `QueryRows` from `SubscribeApplied` translate to a
`DbUpdate` of all inserts, while one from `UnsubscribeApplied` will be
all deletes.
## Legacy subscriptions
"Legacy subscriptions" are removed. These were only used for
`subscribe_to_all_tables`, which as of now is stubbed. I will follow up
with a change to re-implement `subscribe_to_all_tables` by
code-generating a list of all known tables, and having it subscribe to
`select * from {table}` for every table in that list.
## `subscribe_to_all_tables` via a list
Previously, `subscribe_to_all_tables` worked by sending a legacy
subscription with the query `SELECT * FROM *`, which the host had
special handling to expand to subscribing to all tables. As legacy
subscriptions are no longer usable in V2 clients, this can't work.
Instead, we code-generate `SpacetimeModule::ALL_TABLE_NAMES`, a list of
all the known table names. `subscribe_to_all_tables` then maps across
this list to construct a list of queries in the form `SELECT * FROM
{table_name}`, and subscribes to all of those queries. This has the
upside that defining a new table in the module without regenerating
client bindings will no longer result in the client seeing rows of
tables it does not know about and cannot parse.
## Light mode removed
Light mode is no longer meaningful in the V2 WS format, so all code
related to it is removed.
## Internal changes
### Renamed WS messages
The SDK's internal code is updated to account for various renames:
- `QueryId` -> `QuerySetId`, `query_id` -> `query_set_id`.
- `SubscribeMulti` -> `Subscribe`, `UnsubscribeMulti` -> `Unsubscribe`.
## Incidental changes in this PR, not necessary for other client SDKs
### Don't filter out empty ranges in `RowSizeHint`
The Rust implementation of `RowSizeHint` in `BsatnRowList` got regressed
in the base branch to not work with zero-sized rows. This change fixes
that.
# API and ABI breaking changes
Boy howdy is it!
# Expected complexity level and risk
3? Changes ended up being less complicated than I feared, but we do have
some fiddly code here, and we have internal dependencies on the SDK.
# Testing
<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->
- [x] Updated automated test suite.
- Known failures:
- [ ] `subscribe_all_select_star`, which is currently broken because
it's trying to subscribe to rows from private tables. #4241 will fix
this.
---------
Co-authored-by: Jeffrey Dallatezza <jeffreydallatezza@gmail.com>
Co-authored-by: = <cloutiertyler@gmail.com>
|
||
|
|
184d4e9d3f |
Implement server-side support for the v2 websocket protocol (#4213)
# Description of Changes This adds the v2 websocket protocol and adds support on the server side. For context on many of the changes/decisions, you can look at the discussion on https://github.com/clockworklabs/SpacetimeDB/pull/4023. To restate some of the key changes: - The reducer event information is no longer sent with transaction updates (because we don't want to broadcast reducer call information anymore). - If a client calls a reducer, they are sent a `ReducerResult` which includes the outcome of the reducer call and and related row updates for queries that the client is subscribed to. - We no longer dedupe queries that appear in multiple query sets for the same client. This is because we are moving toward per-query storage. - Related to that, Unsubscribe requests have an option to send the related rows. We need this for now, since clients don't have per-query storage implemented yet. - We don't have the json format in v2. Notes for reviewers: - This moves around the messages in `crates/client-api-messages/src/websocket` (into `common`, `v1`, and `v2`), and this renaming of existing messages adds a lot of noise to the PR. - In many places, I chose to duplicate a lot of code to have a v1 version and a v2 version. I went with this to make it easier to remove the v1 version in the future (hopefully we can just fully delete most of the v1 functions). - `module_subscription_manager.rs` has probably has the biggest changes, since we now track queries by query_set_id, and we get to remove some complexity of v1's FormatSwitch. <!-- Please describe your change, mention any related tickets, and so on here. --> # API and ABI breaking changes The v1 protocol still works, though we won't send the reducer event info for v10 modules. # Expected complexity level and risk 4. This touches a lot of places. # Testing Unit testing is pretty minimal for the new code paths. I've done some manual e2e testing with the typescript quickstart, and this has been tested with a different branch implementing the v2 rust client. --------- Co-authored-by: Phoebe Goldman <phoebe@goldman-tribe.org> Co-authored-by: Jeffrey Dallatezza <jeffreydallatezza@gmail.com> |
||
|
|
98585e858d |
Rename with_module_name -> with_database_name (#4267)
# Description of Changes Modules are like programs, databases are like processes. Your client connects to a remote database, not a remote module. <!-- Please describe your change, mention any related tickets, and so on here. --> # API and ABI breaking changes Yep! # Expected complexity level and risk 2? I made this change with find + replace, and it's possible that I borked the edit, or missed some reference somehow. It seems unlikely, however, that this change will have deeper implications we haven't considered. # Testing N/a |
||
|
|
c59ee1ddc3 |
[2.0 Breaking] Add --include-private and default private tables to not generate (#4241)
# Description of Changes Updated the codegen table/function iteration functions to take in a parameter to check visibility in all locations for the supported languages. - Updated the util.rs functions for iterating tables/functions to check for a CodegenVisibility enum (IncludePrivate, or OnlyPublic) - Added a new CodegenOptions struct to pass around the CodegenVisibility and future flags, defaulted visibility to OnlyPublic - Updated the CLI to return a list of all private tables not included (added a TODO to check the --include-private opt): ```bash Optimising module with wasm-opt... Build finished successfully. Skipping private tables during codegen: secret_note, secret_order, secret_person. Generate finished successfully. ``` # API and ABI breaking changes Technically API breaking as the private tables will no longer be available. (GitHub labels are not working at the moment) # Expected complexity level and risk 1 - Simple change the testing took longer # Testing Turns out when you remove private tables you invalidate most of the module_bindings across the system! - [x] Rust test SDK for all languages - [x] C# SDK tests - [x] C# dotnet tests - [x] Updated and checked snap files - [x] Updated Blackholio (Unreal + Unity) module_bindings and tested - [x] Ran Unreal SDK tests --------- Signed-off-by: Jason Larabie <jason@clockworklabs.io> |
||
|
|
a78b056fcc |
Reorganize types generated for typescript clients (#4258)
NOTE: Cherry-picking https://github.com/clockworklabs/SpacetimeDB/pull/4127 from the `2.0-breaking-changes` branch. ## Original PR Description This changes generated types in ts client bindings. We currently generate a few different types of types: reducer args, procedure args, rows, and user defined types. To avoid potential conflicts between these types (for example, if a user defined a type called `FooRow`, and also had a tabled named `foo`, we would end up with two types named `FooRow`), this puts each set of types in a different file and namespace. We also stopped exporting the `xxxRow` types, because there is always another type generated for those. We now have a `types` directory, which has an `index.ts` with user defined types, along with `reducers.ts` and `procedures.ts` for the types generated for reducer/procedure parameters. ``` import type * as Types from './module_bindings/types'; var currentMessages: Types.Message[] = []; ``` or ``` import { type Message } from './module_bindings/types'; var currentMessages: Message[] = []; ``` This has a couple other changes: - For procedure and reducer types, this adds a suffix of `Args`, since we may want types for the return values in the future. - For all of the types, instead of exposing the schema object, we are now giving the typescript type (e.g. `export type Message = __Infer<typeof MessageRow>;`). I couldn't think of a reason for users to want the schema object, so this should save users from needing to do all of the `Infer` boilerplate. This is a breaking change for v2. 2. This only changes typescript, and it should generally make thing easier to use. --------- Co-authored-by: Jeffrey Dallatezza <jeffreydallatezza@gmail.com> |
||
|
|
2560846f22 |
Rust: client query builder (#4003)
# Description of Changes Client Query builder for rust, as per proposal - https://github.com/clockworklabs/SpacetimeDBPrivate/pull/2356. 1. Pach moves query builder to its separate crate, so that it can be shared between module and sdk. 2. Implements `TypedSubscriptionBuilder` in `sdks/rust` as mentioned in proposal 3. Modify codegen to extend types to support query builder as mentioned in proposal 4. a test # API and ABI breaking changes NA, additive changes. # Expected complexity level and risk 2 # Testing Added a test. --------- Signed-off-by: Shubham Mishra <shivam828787@gmail.com> Co-authored-by: joshua-spacetime <josh@clockworklabs.io> |
||
|
|
65c8a8a9da |
Fixes #3240, perf of indexing many rows with same key (#3971)
# Description of Changes Fixes https://github.com/clockworklabs/SpacetimeDB/issues/3240. Non-unique indices are now backed by a type `SameKeyEntry` which holds the `RowPointer`s for the same key. When these `RowPointer`s exceed 4KiB (512 entries), the data structure switches from using an array list to a hash set. # API and ABI breaking changes None # Expected complexity level and risk 2? # Testing Covered by existing tests, though more test will come in future PRs. |
||
|
|
82d5a4f6c0 |
Implement SpacetimeType for Result<T, E> (#3790)
# Description of Changes Closes #3673 *NOTE*: C++ part will be in another PR # Expected complexity level and risk 2 Adding a new type touch everywhere # Testing - [x] Adding smoke and unit test --------- Signed-off-by: Ryan <r.ekhoff@clockworklabs.io> Co-authored-by: rekhoff <r.ekhoff@clockworklabs.io> Co-authored-by: Phoebe Goldman <phoebe@goldman-tribe.org> Co-authored-by: Jason Larabie <jason@clockworklabs.io> |
||
|
|
8fb0bcf922 |
Add UUID built-in convenience type to SpacetimeDB (#3538)
# Description of Changes Closes [#3290](https://github.com/clockworklabs/SpacetimeDB/issues/3290). Adds a new "special" type to SATS, `UUID`, which is represented as the product `{ __uuid__: u128 }`. Adds versions of this type to all of our various languages' module bindings libraries and client SDKs, and updates codegen to recognize it and output references to those named library types. Adds methods for creating new UUIDs according to the V4 (all random) and V7 (timestamp, monotonic counter and random) specifications. # API and ABI breaking changes We add a new type # Expected complexity level and risk 2 it impacts all over the code # Testing - [x] Extends the Rust and Unreal SDK tests, and the associated `module-test` modules in Rust, C# and TypeScript, with uses of UUIDs. - [x] Extends the C# SDK regression tests with uses of UUIDs. - [x] Extends the TypeScript test suite with tests with uses of UUIDs. --------- Signed-off-by: Mario Montoya <mamcx@elmalabarista.com> Co-authored-by: Phoebe Goldman <phoebe@clockworklabs.io> Co-authored-by: Jason Larabie <jason@clockworklabs.io> Co-authored-by: John Detter <4099508+jdetter@users.noreply.github.com> |
||
|
|
afe169ac4a |
Fix the issues with scheduling procedures (#3816)
# Description of Changes This reapplies the patch from #3704, and fixes the issues that were causing it to deadlock. The reason it was deadlocking was that it allowed for the following sequence of events: * `SchedulerActor::handle_queued()` begins mutable tx * `ModuleHost::disconnect_client()` submits call to `call_reducer(tx: None)` * scheduler submits call to `call_reducer(tx: Some)` * `WasmModuleInstance::disconnect_client` now has to try to take tx lock, but the scheduler's call_reducer already holds it and is behind it in the queue So, I moved most of the logic from `handle_queued` back to being executed in the module worker thread, but kept the code in `scheduler.rs` so that it can all be reasoned about locally. Fixes #3645. Should I uncomment the implementation of `ExportFunctionForScheduledTable for F: Procedure` now? # Expected complexity level and risk 2 - there's a chance that this patch hasn't fully fixed the deadlock issue from #3704, but I'm quite confident. # Testing - [x] Manually verified that deadlock no longer occurs - previously, `while true; do python -m smoketests schedule_reducer -k test_scheduled_table_subscription; done` would freeze up in only 2 or 3 iterations, but now it can run for 10 minutes without issues. |
||
|
|
d26f3a10a9 |
Revert "Procedures: fix scheduling (#3704)" (#3774)
This reverts commit
|
||
|
|
b2e37e8008 |
Procedures: fix scheduling (#3704)
# Description of Changes Reworks how `SchedulerActor::handle_queued` works so that it first determines the parameters of the call to a reducer or the parameters of the call to the procedure. This also enables the removal of the special case `call_scheduled_reducer`. Fixes #3645. # API and ABI breaking changes None # Expected complexity level and risk 2 # Testing A test `schedule_procedure` is added. --------- Co-authored-by: Noa <coolreader18@gmail.com> Co-authored-by: Phoebe Goldman <phoebe@goldman-tribe.org> Co-authored-by: rekhoff <r.ekhoff@clockworklabs.io> |
||
|
|
87de672bb3 |
Fix C# module bindings codegen for namespaces with view dispatcher (#3668)
# Description of Changes Closes: #3658 With the work on Views we ran into trouble with the Return Type and certain C# code layout where the types are defined inside the Module class. This fixes the bug in our current approach but needs consideration to possibly be changed entirely. # API and ABI breaking changes N/A # Expected complexity level and risk 1 - Minor change # Testing - [x] Retested with the linked code with and without the namespace - [x] Re-ran regression tests --------- Co-authored-by: John Detter <4099508+jdetter@users.noreply.github.com> Co-authored-by: joshua-spacetime <josh@clockworklabs.io> Co-authored-by: rekhoff <r.ekhoff@clockworklabs.io> |
||
|
|
0a3251708a |
Add ProcedureContext::with_tx (#3638)
# Description of Changes
Adds `ProcedureContext::{with_tx, try_with_tx}`.
Fixes https://github.com/clockworklabs/SpacetimeDB/issues/3515.
# API and ABI breaking changes
None
# Expected complexity level and risk
2
# Testing
An integration test `test_calling_with_tx` is added.
|
||
|
|
565e95bdf4 |
Add Rust client SDK bindings for calling procedures (#3532)
# Description of Changes This commit adds support to the Rust client SDK for calling procedures. Similar to reducers, each `DbContext` implementor has a `pub procedures: RemoteProcedures` field, with methods provided by extension traits for each procedure. Unlike reducers, the provided methods are invoke and invoke-then. Invoke-then takes a `FnOnce` callback to run when the SDK is notified of the procedure's termination status, while invoke ignores that notification. No mechanism is provided for observing procedures invoked by other clients. Procedure callbacks are implemented by storing a map from `request_id` to `ProcedureCallback`, with the callback closure internally knowing how to deserialize the return value. It's mildly unfortunate to deserialize within the callback instead of on the preprocess background task, but it saves significant complexity. This commit also adds a new sdk-test module, `sdk-test-procedures`, and a new Rust test client, `procedure-client`. Together, these are used in two tests of invoking and observing procedures. I've left TODOs for other tests that we should write as we implement additional procedure features. I also had to fix a few minor bugs in the Rust codegen which were not strictly related to procedures: we previously assumed that the sets of reducers and of tables were non-empty, which led to wonky invalid codegen on modules which did not define any reducers or which did not define any tables. I'm sneaking a change to the Nix flake into this PR as well - when initially writing it I had included `cargoArtifacts` (the pre-built and cached dependencies of our actual builds) in its `packages`, but that was neither necessary or useful, and just made building the shell take a long time after dependency changes. # API and ABI breaking changes Breaks the internal interface between the Rust client SDK and codegen, so users will have to re-run `spacetime generate`. # Expected complexity level and risk 2-ish? Pretty simple change to the Rust SDK overall. # Testing - [x] Added new automated integration tests exercising the new functionality. --------- Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com> |
||
|
|
3f1de9e096 |
WASM host execution for procedures (#3498)
# Description of Changes This commit builds support for executing procedures in WASM modules. This includes an HTTP endpoint, `/v1/database/:name_or_address/procedure/:name POST`, as well as an extension to the WS protocol. These new APIs are not wired up to the CLI or SDKs, but I have manually tested the HTTP endpoint via `curl`. The new WS extensions are completely untested. Several TODOs are scattered throughout the new code, most notably for sensibly tracking procedure execution time in the metrics. I also expect that we will want to remove the `procedure_sleep_until` syscall and the `ProcedureContext::sleep_until` method prior to release. # API and ABI breaking changes Adds new APIs and ABIs. # Expected complexity level and risk 3? 4? Unlikely to break existing stuff, 'cause it's mostly additive, but adds plenty of potentially-fragile new stuff. Notably is the first time we're doing anything actually `async`hronous on a database core Tokio worker, and we don't yet have strong evidence of how that will affect reducer execution. # Testing - [x] Manually published `modules/module-test` and executed procedures with the following `curl` invocations: - `curl -X POST -H "Content-Type:application/json" -d '[]' http://localhost:3000/v1/database/module-test/procedure/sleep_one_second` - `curl -X POST -H "Content-Type:application/json" -d '[1223]' http://localhost:3000/v1/database/module-test/procedure/return_value` - [ ] Need to write automated tests. --------- Co-authored-by: Mazdak Farrokhzad <twingoow@gmail.com> |
||
|
|
bf37b2947b |
Add bindings for csharp modules to use JWT claims (#3414)
# Description of Changes This exposes JWT claims for csharp modules, similar to how they are exposed to rust modules in https://github.com/clockworklabs/SpacetimeDB/pull/3288. This adds the new types `AuthCtx` and `JwtClaims`, and adds an `AuthCtx` to the `ReducerContext`. `AuthCtx` represents the credentials associated with the request, and `JwtClaims` represents a jwt token. One difference from the rust version is that I didn't create helpers to build an `AuthCtx` from a jwt payload. The reason is that we would need to be able to compute the identity from the payload claims, which requires a blake3 hash implementation. The first two c# libraries I found had issues at runtime ([Blake3](https://www.nuget.org/packages/Blake3) is wrapping a rust implementation, and [HashifyNet](https://github.com/Deskasoft/HashifyNET/tree/main/HashifyNet/Algorithms/Blake3) seems to be broken by our trimming because it uses reflection heavily). I can look into taking the implementation from `HashifyNet`, since it is MIT licensed, but I don't think we need to block merging on that. # API and ABI breaking changes This adds the new types `AuthCtx` and `JwtClaims`, and adds an `AuthCtx` to the `ReducerContext`. This also adds a csharp wrapper for the get_jwt ABI function added in https://github.com/clockworklabs/SpacetimeDB/pull/3288. # Expected complexity level and risk 2. # Testing This has a very minimal unit test of JwtClaims. I manually tested using this locally with the csharp quickstart, and I was able to print jwt tokens inside the module. |
||
|
|
dbc49b1fd6 |
Add AuthCtx to ReducerContext for rust (#3288)
# Description of Changes This exposes client credentials in reducer calls for rust. # API and ABI breaking changes API Changes: The main API change is the addition of `AuthCtx` and the `sender_auth` in `ReducerContext`. This also adds JwtClaims, which has some helpers for getting commonly used claims. ABI Changes: This adds one new functions `get_jwt`. This uses `st_connection_credentials` to look up the credentials associated with a connection id. This adds ABI version 10.2. # Expected complexity level and risk 2. This adds new ABI functions # Testing I've done some manual testing with modified versions of the quickstart. We should add some examples that use the new API. |
||
|
|
bb43213245 |
Typescript module API (#3327)
# Description of Changes Currently based on #3361 Implements most of the TS module API (not yet a function for type aliases). # Expected complexity level and risk <!-- How complicated do you think these changes are? Grade on a scale from 1 to 5, where 1 is a trivial change, and 5 is a deep-reaching and complex change. This complexity rating applies not only to the complexity apparent in the diff, but also to its interactions with existing and future code. If you answered more than a 2, explain what is complex about the PR, and what other components it interacts with in potentially concerning ways. --> # Testing <!-- Describe any testing you've done, and any testing you'd like your reviewers to do, so that you're confident that all the changes work as expected! --> - [x] Extremely basic module stuff works - [ ] <!-- maybe a test you want a reviewer to do, so they can check it off when they're satisfied. --> --------- Signed-off-by: Noa <coolreader18@gmail.com> Co-authored-by: Tyler Cloutier <cloutiertyler@aol.com> Co-authored-by: = <cloutiertyler@gmail.com> Co-authored-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com> |
||
|
|
351af50578 |
Support BytesSources other than the one for reducer args (#3294)
# Description of Changes Each reducer gets its arguments through an `ArgSource`, a Unix-file-like abstraction for streams of bytes. Prior to this commit, we had an ABI designed as if it could support other args sources, but it actually hardcoded the ID of the reducer args source, and errored elsewhere. This commit extends the `BytesSource` infrastructure to support other bytes sources. This will be useful for exposing JWT payloads and HTTP responses. No other `BytesSource` uses are actually included in this commit, only the infrastructure. This commit also defines a new host call, `bytes_source_remaining_length`. This is intended to allow callers to pre-allocate a buffer correctly sized to read the entire `BytesSource` all at once. The new host function is added to a new ABI minor version, 10.1, so that old SpacetimeDB hosts can detect and reject too-new compiled modules. I have added uses of this new function to `__call_reducer__` in both Rust and C#, even though it's not strictly necessary, and I haven't removed the loop which repeatedly calls `bytes_source_read` and grows the buffer. # API and ABI breaking changes Adds a new ABI minor version, `spacetime_10.1`. This means that old SpacetimeDB hosts will reject new compiled modules. # Expected complexity level and risk 2-ish? WASM ABI code is always fiddly, but this is a pretty simple case. # Testing - [x] New behavior and new host function are both hit through existing tests that instantiate modules and call reducers against them, so I believe automated testing is sufficient. --------- Signed-off-by: Phoebe Goldman <phoebe@goldman-tribe.org> Co-authored-by: rekhoff <r.ekhoff@clockworklabs.io> Co-authored-by: Mazdak Farrokhzad <twingoow@gmail.com> |
||
|
|
1d08167ebd |
Store client credentials in a new system table (#2983)
# Description of Changes This adds a new system table to store the jwt payloads of connected clients. I'm planning to use this system table to expose client claims to modules in subsequent PRs. The new table is called `st_connection_credentials`. It is a **private** system table which stores a mapping from `connection_id` to `jwt_payload`. Note that a jwt payload is a json representation of the clients claims, not a fully signed token. The times when we need to insert and delete these rows closely mirrors that of the existing `st_client` table, with 1.5 exceptions: 1. We weren't previously inserting to `st_client` until after the `OnConnect` reducer ran (even though it was in the same transaction). We want `st_connection_credentials` to be populated before calling the reducer, so that the reducer can use it get the credentials, so I made a change to insert to `st_client` and `st_connection_credentials` before calling the reducer. 2. This difference has not actualized, but when clients start sending refresh tokens, we will probably need to update the credentials stored in this table. This also enforces uniqueness of connection ids. A duplicate connection id will now make the on-connect reducer fail (since it will violate uniqueness when trying to insert to `st_connection_credentials`). # Expected complexity level and risk 2.5 Adding a system table is a bit risky. This is almost rollback safe, with one annoying case that is worth calling out: If a database is created with this system table, opening it with an older version of spacetimedb will only work if there is a snapshot of the database. If we try to load a table without a snapshot, replaying will fail on the first row for that table. This is because we don't write the table schema information to the commit log when creating a database. In practice, this is unlikely to be an issue, because new databases asynchronously trigger a snapshot immediately after creation. Migrating existing databases will be fine. On startup this will detect that there is a missing system table, and add it in a way that writes it to the commit log. Since it is in the commit log, we can open the database with an older version and still understand the data for that table. # Testing There are unit tests that cover opening a database created with an older version (which doesn't have this table). I manually tested opening a migrated database with an older version of spacetimedb. |
||
|
|
8b0e5b1ee3 |
Remove version number and git commit from all but one file in codegen (#3216)
# Description of Changes Closes https://github.com/clockworklabs/SpacetimeDBPrivate/issues/1987 # API and ABI breaking changes This does not affect any APIs but it does affect the code generated # Expected complexity level and risk 1 # Testing <!-- Describe any testing you've done, and any testing you'd like your reviewers to do, so that you're confident that all the changes work as expected! --> - [ ] Snap tests |
||
|
|
b9d30991f1 |
Fix remaining LICENSE files (#3193)
# Description of Changes Apparently, I missed several license files in #3002. I'm not sure what method I was using to find them, but apparently it was insufficient. **This replaces all empty `LICENSE` files with an explicit (symlink to) BSL license, and all apache licenses with symlinks to the root apache license.** This PR does not intentionally change any license terms, so if you see one that changed, **it's a mistake**. # API and ABI breaking changes None # Expected complexity level and risk 1 # Testing ```bash $ find . -name '*LICENSE*' -type f | grep -v '\.meta$' ./crates/sqltest/standards/LICENSE # this one is an external library that we are not allowed to re-license ./LICENSE.txt # this is the root license ``` --------- Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com> |
||
|
|
b6fdc6c3a4 |
Move crates/sdk to sdks/rust (#3181)
# Description of Changes I'm moving `crates/sdk` to `sdks/rust` to be more in line with where the rest of our SDKs are listed. I updated the corresponding paths etc. that pointed to the previous location. This PR is based on https://github.com/clockworklabs/SpacetimeDB/pull/3185, because if we merge this without that, our release scripts will be broken. # API and ABI breaking changes None # Expected complexity level and risk 1 # Testing - [x] Existing CI passes --------- Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com> |