# Description of Changes
Fixes the deadlock in procedures due to holding tx lock across `async`
abis.
More info can be found here -
https://discordapp.com/channels/931210784011321394/1011381307965722774/1458432377574658060.
This patch converts following procedure abis from `async` to sync, which
may seem problematic but it's not as we already hold tx locks in
reducers while blocking the worker thread.
```rust
"spacetime_10.3"::procedure_start_mut_tx,
"spacetime_10.3"::procedure_commit_mut_tx,
"spacetime_10.3"::procedure_abort_mut_tx,
```
# API and ABI breaking changes:
I am surprised that this does not turned out to be ABI breaking change.
Maybe because from wasm side, async abis were always treated as
synchoronous.
# Expected complexity level and risk
2, diff is straightforward but it can have hidden implications.
# Testing
I want someone else to also do the similar testing as mine. Just in
case, I missed something and that appeared it to work.
I did the backward compatible testing as following:
1. I published following module on master branch:
```rust
use spacetimedb::{ProcedureContext, Table};
#[spacetimedb::table(name = my_table)]
struct MyTable {
a: u32,
b: u8,
}
#[spacetimedb::procedure]
fn insert_a_value(ctx: &mut ProcedureContext, a: u32, b: u8) {
ctx.with_tx(|ctx| {
ctx.db.my_table().insert(MyTable { a, b });
});
}
```
2. Called a procedure to insert some values: `spacetime call quick
insert_a_value 1 2`
3. Switched to my branch, re-compiled and restarted the server.
4. Called a procedure again with different values, verfied both old and
new values are present.
---------
Signed-off-by: Shubham Mishra <shivam828787@gmail.com>
Co-authored-by: Phoebe Goldman <phoebe@clockworklabs.io>
# Description of Changes
Provides new WASM ABIs:
- `datastore_index_scan_point_bsatn`
- `datastore_delete_by_index_scan_point_bsatn`
These are then used where applicable to speed up `.find(_)` and friends.
Point scans are also used more internally where applicable.
What remains after this is use in C# module bindings and to expose this
in TS as well.
The PR makes TPS go from roughly 36k to 38k TPS on my machine and also
makes a difference in flamegraphs where the time spent in some index
scans are substantially decreased.
# API and ABI breaking changes
None
# Expected complexity level and risk
3? This touches the datastore an how we expose it to modules.
# Testing
Some existing tests now exercise the new ABIs by changing what
`.find(_)` and friends do.
---------
Signed-off-by: Mazdak Farrokhzad <twingoow@gmail.com>
# Description of Changes
Closes#3517 .
With this PR, procedures (at least, those defined in Rust modules) can
perform HTTP requests! This is performed through a new field on the
`ProcedureContext`, `http: HttpClient`, which has a method `send` for
sending an `http::Request`, as well as a convenience wrapper `get`.
Internally, these methods hit the `procedure_http_request` ABI call /
host function, which uses reqwest to perform an HTTP request. The
request is run with a user-configurable timeout which defaults and is
clamped to 500 ms.
Rather than exposing the HTTP stream to modules, we download the entire
response body immediately, within the same timeout.
I've added an example usage of `get` to `module-test` which performs a
request against `localhost:3000` to read its own schema/moduledef.
This PR also makes all procedure-related definitions in the Rust module
bindings library `#[cfg(feature = "unstable")]`, as per #3644 . The
rename of the `/v1/database/:name/procedure/:name` route is not included
in this PR, so this does not close#3644 .
Left as TODOs are:
- Metrics for recording request and response size.
- Improving performance by stashing a long-lived `reqwest::Client`
someplace.
Currently we build a new `Client` for each request.
- Improving performance (possibly) by passing the request-future to the
global tokio executor
rather than running it on the single-threaded database executor.
# API and ABI breaking changes
Adds new APIs, which are marked as unstable. Adds a new ABI, which is
not unstable in any meaningful way (we can't really do that). Marks
unreleased APIs as unstable. Does not affect any pre-existing
already-released APIs or ABIs.
# Expected complexity level and risk
3 or so: networking is scary, and even though we impose a timeout which
prevents these connections from being truly long-lived, they're still
potentially long-lived on the scale of Tokio futures. It's possible that
running them on the database core is problematic in some way, and so
what I've left as a performance TODO could actually be a
concurrency-correctness issue.
# Testing
- [x] Manually wrote and executed some procedures which make HTTP
requests.
- [x] Added two automated tests to the `sdk-test` suite,
`procedure::http_ok` and `procedure::http_err`, which make successful
and failing requests respectively, then return its result. A client then
makes some assertions about the result.
---------
Co-authored-by: Noa <coolreader18@gmail.com>
# 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.
# 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>
# 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`:
```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.
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
- [x] Added a procedure definition to `module-test`, saw that it
typechecks.
- [x] Executed same procedure definition using #3390 , the prototype
implementation this PR draws from.
# 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.
# 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>
# Description of Changes
We recently merged several repos together. This PR clarifies the license
terms for several subdirectories, as well as the relationship between
the licenses.
The licenses in our subdirectories have become symbolic links to
licenses in our toplevel `licenses` directory. For any particular
subdirectory's license file in the diff, you can click `... -> View
file` and then click on the text that says "Symbolic Link" on that page.
This will take you to the license file that it links to.
I have also updated the `tools/upgrade-version` script to update the
change date in the new `licenses/BSL.txt` file.
# API and ABI breaking changes
None.
# Expected complexity level and risk
1
# Testing
None. Only changes to license files.
---------
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
* Added license files for the primitives crate
* Fixed version number dependency thing
---------
Co-authored-by: Tyler Cloutier <cloutiertyler@aol.com>
This removes very unused, commented out code. One category is for
unused plumbing from the bindings towards the instance. The other
is a bit of unused performance instrumentation.