diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f7873395085..b1e86c3d056 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -737,3 +737,51 @@ jobs: echo 'Error: Bindings are dirty. Please run `sdks/csharp/tools~/gen-regression-tests.sh`.' exit 1 } + nix-flake-check: + name: Nix flake check + runs-on: spacetimedb-new-runner + container: + image: localhost:5000/spacetimedb-ci:latest + options: >- + --privileged + permissions: + contents: read + steps: + - uses: actions/checkout@v4 + - uses: cachix/install-nix-action@v31 + with: + github_access_token: ${{ secrets.GITHUB_TOKEN }} + - name: Expose nix to PATH + shell: bash + run: | + set -euo pipefail + + # GitHub normally provides these, but some container+runner setups don't. + PATH_FILE="${GITHUB_PATH:-/github/path}" + ENV_FILE="${GITHUB_ENV:-/github/env}" + BASH_ENV_FILE="${BASH_ENV:-/github/bash_env}" + + # Ensure the files exist + mkdir -p "$(dirname "$PATH_FILE")" "$(dirname "$ENV_FILE")" "$(dirname "$BASH_ENV_FILE")" + : > "$PATH_FILE" || true + : > "$ENV_FILE" || true + : > "$BASH_ENV_FILE" || true + + echo "/root/.nix-profile/bin" >> "$PATH_FILE" + echo "PATH=/root/.nix-profile/bin:\$PATH" >> "$ENV_FILE" + echo ". /root/.nix-profile/etc/profile.d/nix.sh" >> "$BASH_ENV_FILE" + - name: Nix flake check + shell: bash + run: | + set -euo pipefail + export NIX_CONFIG=$'log-lines = 200000\nmax-jobs = 8\ncores = 8\n' + export CARGO_BUILD_JOBS=1 + export RUST_BACKTRACE=full + nix flake check -L --show-trace --print-build-logs + - name: Dump jemalloc configure log (on failure) + if: ${{ failure() }} + shell: bash + run: | + set -euxo pipefail + # Find any jemalloc config.log produced in the workspace build dir + find /build/source -path '*tikv-jemalloc-sys*' -name config.log -print -exec tail -n 300 {} \; || true diff --git a/Cargo.lock b/Cargo.lock index aa39b4057de..6e5db36df25 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3001,7 +3001,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.62.2", + "windows-core 0.61.2", ] [[package]] @@ -7229,42 +7229,45 @@ dependencies = [ [[package]] name = "spacetimedb" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8679cf54a7a653e6bc612bef28c219f98b9274308d8aae1e86046ed685db48b1" +version = "1.11.1" dependencies = [ + "anyhow", "bytemuck", + "bytes", "derive_more 0.99.20", "getrandom 0.2.16", + "http 1.3.1", + "insta", "log", "rand 0.8.5", "scoped-tls", - "spacetimedb-bindings-macro 1.6.0", - "spacetimedb-bindings-sys 1.6.0", - "spacetimedb-lib 1.6.0", - "spacetimedb-primitives 1.6.0", + "serde_json", + "spacetimedb-bindings-macro 1.11.1", + "spacetimedb-bindings-sys 1.11.1", + "spacetimedb-lib 1.11.1", + "spacetimedb-primitives 1.11.1", + "trybuild", ] [[package]] name = "spacetimedb" version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fadbe821ba7bf725770100bda495ae5757b8a4a035d065a210937fe8a27ffb36" dependencies = [ - "anyhow", "bytemuck", "bytes", "derive_more 0.99.20", "getrandom 0.2.16", "http 1.3.1", - "insta", "log", "rand 0.8.5", "scoped-tls", "serde_json", - "spacetimedb-bindings-macro 1.11.1", - "spacetimedb-bindings-sys 1.11.1", - "spacetimedb-lib 1.11.1", - "spacetimedb-primitives 1.11.1", - "trybuild", + "spacetimedb-bindings-macro 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", + "spacetimedb-bindings-sys 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", + "spacetimedb-lib 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", + "spacetimedb-primitives 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7330,44 +7333,44 @@ dependencies = [ [[package]] name = "spacetimedb-bindings-macro" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a930242493f5c875ab96903eb40fb6a90c4d3ae99597fd51da569ff22769a03" +version = "1.11.1" dependencies = [ "heck 0.4.1", "humantime", "proc-macro2", "quote", - "spacetimedb-primitives 1.6.0", + "spacetimedb-primitives 1.11.1", "syn 2.0.107", ] [[package]] name = "spacetimedb-bindings-macro" version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4deb0b154961123ff3459437e4167b4210bd4e4255071ce4e0053ef0c636502" dependencies = [ "heck 0.4.1", "humantime", "proc-macro2", "quote", - "spacetimedb-primitives 1.11.1", + "spacetimedb-primitives 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", "syn 2.0.107", ] [[package]] name = "spacetimedb-bindings-sys" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e565dfcdd2dc3f58e0178052ec1c8ce710b013482d4fa50b511ba786a2c3bc68" +version = "1.11.1" dependencies = [ - "spacetimedb-primitives 1.6.0", + "spacetimedb-primitives 1.11.1", ] [[package]] name = "spacetimedb-bindings-sys" version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0044bb75deda2611ce3f2e175eb5288f3ac4652c774cc034e7fdb15cda81c14f" dependencies = [ - "spacetimedb-primitives 1.11.1", + "spacetimedb-primitives 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7401,7 +7404,6 @@ dependencies = [ "names", "notify 7.0.0", "percent-encoding", - "portpicker", "predicates", "pretty_assertions", "quick-xml 0.31.0", @@ -7424,6 +7426,7 @@ dependencies = [ "spacetimedb-paths", "spacetimedb-primitives 1.11.1", "spacetimedb-schema", + "spacetimedb-testing", "syntect", "tabled", "tar", @@ -7845,50 +7848,51 @@ dependencies = [ [[package]] name = "spacetimedb-lib" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ba57c8f1983bb144ee7e1ff28aa5882ca437f67c14a14daad4bf61d31f7040d" +version = "1.11.1" dependencies = [ "anyhow", "bitflags 2.10.0", "blake3", + "bytes", "chrono", "derive_more 0.99.20", "enum-as-inner", + "enum-map", "hex", + "insta", "itertools 0.12.1", - "spacetimedb-bindings-macro 1.6.0", - "spacetimedb-primitives 1.6.0", - "spacetimedb-sats 1.6.0", + "log", + "proptest", + "proptest-derive", + "ron", + "serde", + "serde_json", + "spacetimedb-bindings-macro 1.11.1", + "spacetimedb-memory-usage", + "spacetimedb-metrics", + "spacetimedb-primitives 1.11.1", + "spacetimedb-sats 1.11.1", "thiserror 1.0.69", ] [[package]] name = "spacetimedb-lib" version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fca841a1533afd647d2a2319ea377ba372d490f95bedad79d473a5eb1e521c93" dependencies = [ "anyhow", "bitflags 2.10.0", "blake3", - "bytes", "chrono", "derive_more 0.99.20", "enum-as-inner", - "enum-map", "hex", - "insta", "itertools 0.12.1", "log", - "proptest", - "proptest-derive", - "ron", - "serde", - "serde_json", - "spacetimedb-bindings-macro 1.11.1", - "spacetimedb-memory-usage", - "spacetimedb-metrics", - "spacetimedb-primitives 1.11.1", - "spacetimedb-sats 1.11.1", + "spacetimedb-bindings-macro 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", + "spacetimedb-primitives 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", + "spacetimedb-sats 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.69", ] @@ -7964,27 +7968,28 @@ dependencies = [ [[package]] name = "spacetimedb-primitives" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dcd64c6970ca59e7b71e51952cf1a71bae2652b1eb736c19a7e528f3874894a" +version = "1.11.1" dependencies = [ "bitflags 2.10.0", "either", + "enum-as-inner", "itertools 0.12.1", "nohash-hasher", + "proptest", + "spacetimedb-memory-usage", ] [[package]] name = "spacetimedb-primitives" version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "052a89c7fb459a9c8bdd1ec2744079b89e86c0626a2a70ea346afd74a40926c0" dependencies = [ "bitflags 2.10.0", "either", "enum-as-inner", "itertools 0.12.1", "nohash-hasher", - "proptest", - "spacetimedb-memory-usage", ] [[package]] @@ -8006,15 +8011,16 @@ dependencies = [ [[package]] name = "spacetimedb-sats" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae61d8f88bda21f56c143bc9b4ddc20100ff08ae4fed0b9444509f7c3ca4339" +version = "1.11.1" dependencies = [ + "ahash 0.8.12", "anyhow", "arrayvec", "bitflags 2.10.0", + "blake3", "bytemuck", "bytes", + "bytestring", "chrono", "decorum", "derive_more 0.99.20", @@ -8022,26 +8028,33 @@ dependencies = [ "ethnum", "hex", "itertools 0.12.1", + "proptest", + "proptest-derive", + "rand 0.9.2", "second-stack", + "serde", + "serde_json", "sha3", "smallvec", - "spacetimedb-bindings-macro 1.6.0", - "spacetimedb-primitives 1.6.0", + "spacetimedb-bindings-macro 1.11.1", + "spacetimedb-memory-usage", + "spacetimedb-metrics", + "spacetimedb-primitives 1.11.1", "thiserror 1.0.69", + "uuid", ] [[package]] name = "spacetimedb-sats" version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5cae97b2b58ec2bf606c8546b6d6b008b1a3412a57437694a3f9723c5ebb960" dependencies = [ - "ahash 0.8.12", "anyhow", "arrayvec", "bitflags 2.10.0", - "blake3", "bytemuck", "bytes", - "bytestring", "chrono", "decorum", "derive_more 0.99.20", @@ -8049,20 +8062,12 @@ dependencies = [ "ethnum", "hex", "itertools 0.12.1", - "proptest", - "proptest-derive", - "rand 0.9.2", "second-stack", - "serde", - "serde_json", "sha3", "smallvec", - "spacetimedb-bindings-macro 1.11.1", - "spacetimedb-memory-usage", - "spacetimedb-metrics", - "spacetimedb-primitives 1.11.1", + "spacetimedb-bindings-macro 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", + "spacetimedb-primitives 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.69", - "uuid", ] [[package]] @@ -8258,7 +8263,9 @@ dependencies = [ "env_logger 0.10.2", "lazy_static", "log", + "portpicker", "rand 0.9.2", + "reqwest 0.12.24", "serde", "serde_json", "serial_test", @@ -9521,7 +9528,7 @@ version = "0.1.0" dependencies = [ "anyhow", "log", - "spacetimedb 1.6.0", + "spacetimedb 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 7836656dd29..f5c982b8522 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -229,6 +229,7 @@ percent-encoding = "2.3" petgraph = { version = "0.6.5", default-features = false } pin-project-lite = "0.2.9" pgwire = { version = "0.34.2", default-features = false, features = ["server-api", "pg-ext-types"] } +portpicker = "0.1" postgres-types = "0.2.5" pretty_assertions = { version = "1.4", features = ["unstable"] } proc-macro2 = "1.0" diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index e0d3663176c..d57fb77e28a 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -89,8 +89,8 @@ pretty_assertions.workspace = true fs_extra.workspace = true assert_cmd = "2" predicates = "3" -portpicker = "0.1" reqwest = { workspace = true, features = ["blocking", "json"] } +spacetimedb-testing.path = "../testing" [target.'cfg(not(target_env = "msvc"))'.dependencies] tikv-jemallocator = { workspace = true } diff --git a/crates/cli/tests/publish.rs b/crates/cli/tests/publish.rs index a4df1bf88ca..175f29f72d5 100644 --- a/crates/cli/tests/publish.rs +++ b/crates/cli/tests/publish.rs @@ -1,7 +1,5 @@ -mod util; - -use crate::util::SpacetimeDbGuard; use assert_cmd::cargo::cargo_bin_cmd; +use spacetimedb_testing::SpacetimeDbGuard; #[test] fn cli_can_publish_spacetimedb_on_disk() { diff --git a/crates/cli/tests/server.rs b/crates/cli/tests/server.rs index 3e953f174d0..b5dfc441769 100644 --- a/crates/cli/tests/server.rs +++ b/crates/cli/tests/server.rs @@ -1,7 +1,5 @@ -mod util; - -use crate::util::SpacetimeDbGuard; use assert_cmd::cargo::cargo_bin_cmd; +use spacetimedb_testing::SpacetimeDbGuard; #[test] fn cli_can_ping_spacetimedb_on_disk() { diff --git a/crates/cli/tests/util.rs b/crates/cli/tests/util.rs deleted file mode 100644 index 1bb5a99fb15..00000000000 --- a/crates/cli/tests/util.rs +++ /dev/null @@ -1,150 +0,0 @@ -use std::{ - env, - io::{BufRead, BufReader}, - net::SocketAddr, - process::{Child, Command, Stdio}, - sync::{Arc, Mutex}, - thread::{self, sleep}, - time::{Duration, Instant}, -}; - -use reqwest::blocking::Client; - -fn find_free_port() -> u16 { - portpicker::pick_unused_port().expect("no free ports available") -} - -pub struct SpacetimeDbGuard { - pub child: Child, - pub host_url: String, - pub logs: Arc>, -} - -// Remove all Cargo-provided env vars from a child process. These are set by the fact that we're running in a cargo -// command (e.g. `cargo test`). We don't want to inherit any of these to a child cargo process, because it causes -// unnecessary rebuilds. -impl SpacetimeDbGuard { - /// Start `spacetimedb` in a temporary data directory via: - /// cargo run -p spacetimedb-cli -- start --data-dir --listen-addr - pub fn spawn_in_temp_data_dir() -> Self { - let temp_dir = tempfile::tempdir().expect("failed to create temp dir"); - let data_dir = temp_dir.path().display().to_string(); - - Self::spawn_spacetime_start(&["start", "--data-dir", &data_dir]) - } - - fn spawn_spacetime_start(extra_args: &[&str]) -> Self { - let port = find_free_port(); - let addr: SocketAddr = format!("127.0.0.1:{port}").parse().unwrap(); - let address = addr.to_string(); - let host_url = format!("http://{}", addr); - - // Workspace root for `cargo run -p ...` - let workspace_dir = env!("CARGO_MANIFEST_DIR"); - - Self::build_prereqs(workspace_dir); - let mut cargo_args = vec!["run", "-p", "spacetimedb-cli", "--"]; - - cargo_args.extend(extra_args); - cargo_args.extend(["--listen-addr", &address]); - - let (child, logs) = Self::spawn_child(workspace_dir, &cargo_args); - - let guard = SpacetimeDbGuard { child, host_url, logs }; - guard.wait_until_http_ready(Duration::from_secs(10)); - guard - } - - // Ensure standalone is built before we start, if that’s needed. - // This is best-effort and usually a no-op when already built. - // Also build the CLI before running it to avoid that being included in the - // timeout for readiness. - fn build_prereqs(workspace_dir: &str) { - let targets = ["spacetimedb-standalone", "spacetimedb-cli"]; - - for pkg in targets { - let mut cmd = Command::new("cargo"); - let _ = cmd - .args(["build", "-p", pkg]) - .current_dir(workspace_dir) - .status() - .unwrap_or_else(|_| panic!("failed to build {}", pkg)); - } - } - - fn spawn_child(workspace_dir: &str, args: &[&str]) -> (Child, Arc>) { - let mut cmd = Command::new("cargo"); - let mut child = cmd - .args(args) - .current_dir(workspace_dir) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .spawn() - .expect("failed to spawn spacetimedb-cli"); - - let logs = Arc::new(Mutex::new(String::new())); - - // Attach stdout logger - if let Some(stdout) = child.stdout.take() { - let logs_clone = logs.clone(); - thread::spawn(move || { - let reader = BufReader::new(stdout); - for line in reader.lines().map_while(Result::ok) { - let mut buf = logs_clone.lock().unwrap(); - buf.push_str("[STDOUT] "); - buf.push_str(&line); - buf.push('\n'); - } - }); - } - - // Attach stderr logger - if let Some(stderr) = child.stderr.take() { - let logs_clone = logs.clone(); - thread::spawn(move || { - let reader = BufReader::new(stderr); - for line in reader.lines().map_while(Result::ok) { - let mut buf = logs_clone.lock().unwrap(); - buf.push_str("[STDERR] "); - buf.push_str(&line); - buf.push('\n'); - } - }); - } - - (child, logs) - } - - fn wait_until_http_ready(&self, timeout: Duration) { - let client = Client::new(); - let deadline = Instant::now() + timeout; - - while Instant::now() < deadline { - let url = format!("{}/v1/ping", self.host_url); - - if let Ok(resp) = client.get(&url).send() { - if resp.status().is_success() { - return; // Fully ready! - } - } - - sleep(Duration::from_millis(50)); - } - panic!("Timed out waiting for SpacetimeDB HTTP /v1/ping at {}", self.host_url); - } -} - -impl Drop for SpacetimeDbGuard { - fn drop(&mut self) { - // Best-effort cleanup. - let _ = self.child.kill(); - let _ = self.child.wait(); - - // Only print logs if the test is currently panicking - if std::thread::panicking() { - if let Ok(logs) = self.logs.lock() { - eprintln!("\n===== SpacetimeDB child logs (only on failure) =====\n{}\n====================================================", *logs); - } - } - } -} diff --git a/crates/standalone/src/lib.rs b/crates/standalone/src/lib.rs index cd2da537a54..46d551cf06f 100644 --- a/crates/standalone/src/lib.rs +++ b/crates/standalone/src/lib.rs @@ -4,7 +4,7 @@ pub mod util; pub mod version; use crate::control_db::ControlDb; -use crate::subcommands::{extract_schema, start}; +pub use crate::subcommands::{extract_schema, start}; use anyhow::Context as _; use async_trait::async_trait; use clap::{ArgMatches, Command}; diff --git a/crates/testing/Cargo.toml b/crates/testing/Cargo.toml index 2d06a8dddce..f79d0caf2b9 100644 --- a/crates/testing/Cargo.toml +++ b/crates/testing/Cargo.toml @@ -28,6 +28,8 @@ lazy_static.workspace = true rand.workspace = true tempfile.workspace = true serde.workspace = true +portpicker.workspace = true +reqwest = { workspace = true, features = ["blocking"] } [dev-dependencies] serial_test.workspace = true diff --git a/crates/testing/src/lib.rs b/crates/testing/src/lib.rs index f99a46f4769..b41ab93ceee 100644 --- a/crates/testing/src/lib.rs +++ b/crates/testing/src/lib.rs @@ -7,8 +7,11 @@ use std::env; use std::process::Command; pub mod modules; +mod run_standalone; pub mod sdk; +pub use run_standalone::SpacetimeDbGuard; + #[track_caller] pub fn invoke_cli(paths: &SpacetimePaths, args: &[&str]) { lazy_static::lazy_static! { diff --git a/crates/testing/src/run_standalone.rs b/crates/testing/src/run_standalone.rs new file mode 100644 index 00000000000..70fdb8cf95e --- /dev/null +++ b/crates/testing/src/run_standalone.rs @@ -0,0 +1,106 @@ +use crate::modules::start_runtime; +use reqwest::blocking::Client; +use spacetimedb::util::jobs::JobCores; +use std::{ + net::SocketAddr, + thread::{sleep, JoinHandle}, + time::{Duration, Instant}, +}; +use tempfile::TempDir; + +fn find_free_port() -> u16 { + portpicker::pick_unused_port().expect("no free ports available") +} + +pub struct SpacetimeDbGuard { + thread: Option>, + pub host_url: String, + cancel: Option>, +} + +// Remove all Cargo-provided env vars from a child process. These are set by the fact that we're running in a cargo +// command (e.g. `cargo test`). We don't want to inherit any of these to a child cargo process, because it causes +// unnecessary rebuilds. +impl SpacetimeDbGuard { + pub fn spawn_in_temp_data_dir() -> Self { + Self::spawn_spacetime_start(&[]) + } + + fn run_spacetime(args: Vec, cancel: tokio::sync::oneshot::Receiver<()>, _temp_dir: TempDir) { + let runtime = start_runtime(); + let args = spacetimedb_standalone::start::cli().try_get_matches_from(args).unwrap(); + runtime.block_on(async { + tokio::select! { + _ = spacetimedb_standalone::start::exec(&args, JobCores::without_pinned_cores(runtime.handle().clone())) => (), + _ = cancel => (), + } + }); + } + + fn spawn_spacetime_start(extra_args: &[&str]) -> Self { + let port = find_free_port(); + let addr: SocketAddr = format!("127.0.0.1:{port}").parse().unwrap(); + let address = addr.to_string(); + let host_url = format!("http://{}", addr); + + let temp_dir = tempfile::tempdir().expect("failed to create temp dir"); + let data_dir = temp_dir.path().display().to_string(); + + let mut args = vec![ + "start".to_string(), + "--data-dir".to_string(), + data_dir.to_string(), + "--listen-addr".to_string(), + address, + ]; + + args.extend(extra_args.iter().map(ToString::to_string)); + + let (cancel, cancel_recv) = tokio::sync::oneshot::channel(); + let thread = std::thread::spawn(move || { + Self::run_spacetime(args, cancel_recv, temp_dir); + }); + + let guard = SpacetimeDbGuard { + thread: Some(thread), + cancel: Some(cancel), + host_url, + }; + guard.wait_until_http_ready(Duration::from_secs(10)); + guard + } + + fn wait_until_http_ready(&self, timeout: Duration) { + let client = Client::new(); + let deadline = Instant::now() + timeout; + + while Instant::now() < deadline { + let url = format!("{}/v1/ping", self.host_url); + + if let Ok(resp) = client.get(&url).send() { + if resp.status().is_success() { + return; // Fully ready! + } + } + + sleep(Duration::from_millis(50)); + } + panic!("Timed out waiting for SpacetimeDB HTTP /v1/ping at {}", self.host_url); + } +} + +impl Drop for SpacetimeDbGuard { + fn drop(&mut self) { + let _ = self.cancel.take().unwrap().send(()); + if let Err(e) = self.thread.take().unwrap().join() { + let msg = if let Some(s) = e.downcast_ref::() { + s + } else if let Some(s) = e.downcast_ref::<&str>() { + s + } else { + "dyn Any" + }; + panic!("standalone process failed by panic: {msg}") + } + } +}