* Always send TransactionUpdate to the sender
This commit changes transaction update broadcast to always send an
update to the sender, even if the sender is not subscribed to any
data that was committed. In such case the transaction update is sent
with an empty database update.
* Remove debug printlns
* Update code after rebase
* Fix test
* Update crates/core/src/subscription/module_subscription_manager.rs
Co-authored-by: Mazdak Farrokhzad <twingoow@gmail.com>
Signed-off-by: Piotr Sarnacki <drogus@gmail.com>
* Extract sending message with error handing in module_subscription_manager
* Bring back a new line
* SDK test that the client is notified of a reducer it called
* cleanup subscription code a bit
* Fix merge problem
* Lint + fmt
* Fix test
---------
Signed-off-by: Piotr Sarnacki <drogus@gmail.com>
Co-authored-by: Mazdak Farrokhzad <twingoow@gmail.com>
Co-authored-by: Phoebe Goldman <phoebe@goldman-tribe.org>
* Prevent importing an identity with a name that already exists in the
config
* Make identity naming more consistent
* Fix clippy lints
* Several bug fixes and UX improvements
* Prevent someone from adding the same identity twice
* Fix lint
* [jdetter/make-identity-naming-more-consistent]: review
* [jdetter/make-identity-naming-more-consistent]: review
* [jdetter/make-identity-naming-more-consistent]: review
* Reverted file
---------
Co-authored-by: John Detter <no-reply@boppygames.gg>
Co-authored-by: Zeke Foppa <github.com/bfops>
## Description of Changes
Instead of a separate TableOp enum, and 4 fields to handle insert/delete
metadata in DbOp, use a nullable struct that contains non-nullable
object + bytes pair internally:
- if `insert` is present (non-nullable) and `delete` is nullable, that
naturally indicates insert operation
- if `insert` is nullable and `delete` is not, that's a delete
- if both are non-nullable, it's an update
- if both are null, it's an internal "no change" state
This simplifies and shortens update handling as well as reduces risk of
state getting out of sync - e.g. TableOp saying that the operation is
insert should exist but field containing inserted value being null. Now
nullable struct itself communicates whether there is an insert or not,
without a separate enum.
## API
- [ ] This is an API breaking change to the SDK
*If the API is breaking, please state below what will break*
## Requires SpacetimeDB PRs
*List any PRs here that are required for this SDK change to work*
## Description of Changes
Initially just fixed the nullability issues / warnings, but in the
process did a few more minor drive-by refactorings.
## API
- [ ] This is an API breaking change to the SDK
*If the API is breaking, please state below what will break*
## Requires SpacetimeDB PRs
*List any PRs here that are required for this SDK change to work*
* Add SDK test for `SELECT * FROM *`
Which doesn't pass, because we broke it.
* Fix select * from *
---------
Co-authored-by: Phoebe Goldman <phoebe@goldman-tribe.org>
* Create a lockfile when opening config files
In the past, we've had issues where multiple concurrent CLI processes
would race to read and write the CLI config file,
leading to data loss.
We considered using `flock`/`LockFileEx` and blocking until the file became available,
but unfortunately it's not possible to atomically create and lock a nonexistent file,
which we need to do in the case where the configuration doesn't yet exist.
Instead, we opt for a classic lockfile-based scheme:
Before opening a config file `foo.conf`, attempt to exclusively create `foo.lock`,
and panic if the exclusive creation fails.
Once it becomes clear that we will not write the config any more,
i.e. in `Config::drop`,
delete the lockfile, allowing another process to operate.
This means that attempting to run multiple concurrent Spacetime CLI processes
with the same config file is now a hard error.
* Fix CI failures
This commit fixes two CI failures:
- `spacetime start`, and a few other CLI subcommands, do not access their `Config` at all,
but the CLI constructs it unconditionally in `main`,
which made it an error to run any CLI command while `spacetime start` was running.
This is fixed by having subcommands which don't need a `Config`
drop it before doing anything.
- Contrary to my assumption,
the test configuration created by `Config::new_with_localhost` does get `drop`ped,
because the test harness `clone`s is and passes an owned version to the CLI.
This was causing it to attempt to delete the empty path, which failed.
This is fixed by having the home configuration be `Option`al,
and setting it to `None` in tests.
* Clap before config because they suppress destructors
Perform Clap argument parsing as the very first thing in a CLI process,
before locking the config,
because Clap calls `exit` directly on error rather than panicing
(presumably to have more control over error output),
which prevents destructors from running,
leaving stale lockfiles.
* Encapsulate lockfile logic in a type
Also deduplicate logic for finding config file paths.
* Define `create_parent_dir` helper with comments
* Replace `drop` calls with more explicit `Config::release_lock`.
## Description of Changes
There is only one place where we use Channels, and it's to create and await a channel with one element - which is functionally the same as a more precise and low-weight TaskCompletionSource.
Switching also makes the SDK compatible with the widely supported .NET Standard 2.1 subset, which is supported natively in Unity and allows to remove a custom System.Threading.Channels package from Unity SDK dependencies.
## API
- [ ] This is an API breaking change to the SDK
*If the API is breaking, please state below what will break*
## Requires SpacetimeDB PRs
*List any PRs here that are required for this SDK change to work*
## Description of Changes
Instead of using custom class hierarchy of messages, we can just use
native C# lambdas stored as Actions.
OnConnectError case can be further simplified by merging two branches
for different exception types into one.
## API
- [ ] This is an API breaking change to the SDK
*If the API is breaking, please state below what will break*
## Requires SpacetimeDB PRs
*List any PRs here that are required for this SDK change to work*
The documentation promised to not collect payload values during folds
(i.e. replaying), but the code did so anyway. This patch makes it so
only values required to satisfy the `Visitor` trait are allocated when
folding.
With C# records - which are available since C# 9, so covers Unity requirements as well - we can use subclassing and pattern matching to get sum types that look a lot more like Rust tagged enums.
This is a breaking change but IMO worth it for the better API going forward.
* remove dead code wrt. Table
* simplify DbProgram: Insert/Update/Delete only use DbTables
* consistency: move CrudExpr::Update logic to own function
* use TxMode::unwrap_mut more
Minor refactoring that extracts common part of subscription and transaction update handling into a separate function, so that the main logic in `OnMessageProcessComplete` is a bit more straightforward and handles all event types with a sinlge `switch` instead of 3 separate `switch`es.
This is a small no-op step that makes further refactoring and optimisation of said common logic a bit easier.
* Merge ByteArrayComparers
Merge various mismatched implementation of byte array comparison/hashing into a single utils class (choosing the most efficient implementation already present).
* Forward hex conversion too
* Use const for Identity & Address sizes
* C#: rename DbEventArgs to ReducerContext
This is no longer an event type, so remove subclassing and rename to match the Rust API.
* Update ReducerContext argument name
* cleanup bsatn ser/de roundtrip test
* fmt::Display for FieldExpr: don't use type_of
* make type_of partial and sound
* type_of: address review feedback
* Remove C# GetArgsAsObjectArray
This is a weird "duck-typed" API that has one usage in BitCraft, but it's easy to replace with either real reflection or strong-typed interfaces.
* Update csharp.rs
Signed-off-by: Ingvar Stepanyan <me@rreverser.com>
---------
Signed-off-by: Ingvar Stepanyan <me@rreverser.com>
* Make `Page` always fully init
Per discussion on the snapshotting proposal,
this PR changes the type of `Page.row_data` to `[u8; _]`,
where previously it was `[MaybeUninit<u8>; _]`.
This turns out to be shockingly easy,
as our serialization codepaths never write padding bytes into a page.
The only place pages ever became `poison` was the initial allocation;
changing this to `alloc_zeroed` causes the `row_data` to always be valid at `[u8; _]`.
The majority of this diff is replacing `MaybeUninit`-specific operators
with their initialized equivalents,
and updating comments and documentation to reflect the new requirements.
This change also revealed a bug in the benchmarks
introduced when we swapped the order of sum tags and payloads
( https://github.com/clockworklabs/SpacetimeDB/pull/1063 ),
where benchmarks used a hardcoded offset for the tag which had not been updated.
* Update blake3
Blake3 only supports running under Miri as of 1.15.1, the latest version.
Prior versions hard-depended on SIMD intrinsics which Miri doesn't support.
* Address Mazdak's review.
Still pending his agreeing with me that `poison` is a better name than `uninit`.
* "Poison" -> "uninit"
Against my best wishes, for consistency with the broader Rust community's poor choices.
* Remove unnecessary `unsafe` blocks
* More unnecessary `unsafe`; remove forgotten SAFETY comments