Make it so `HostController` manages both the module host (wasm
machinery) and the database (`RelationalDB` / `DatabaseInstanceContext`)
of spacetime databases deployed to a server.
The `DatabaseInstanceContextController` (DBIC) is removed in the
process.
This allows to make database accesses panic-safe, in that uncaught
panics will cause all resouces to be released and the database to be
restarted on subsequent access. This is a prerequisite for #985.
It also allows to move towards storage of the module binary directly in
the database / commitlog. This patch, however, makes some contortions in
order to **not** introduce a breaking change just yet.
* 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`.
This patch attempts to integrate the new commitlog with the minimum
changes.
Most of the diff comes from deletions of the legacy log and the need to
adjust tests due to the requirement for a tokio runtime when a durable
database is used in tests.
The "meat" of the patch are the `RelationalDB` constructors,
`RelationalDB::commit_tx`, and the replay logic in
`locking_tx_datastore`.
While `DataKey` is gone, there is still some redundant data being passed
around, which will be addressed in the follow-up patch.