From 7d430024297f3687d2a59f3cf8f6464009b5f321 Mon Sep 17 00:00:00 2001 From: Peter Wagenet Date: Mon, 10 Aug 2026 20:48:36 -0700 Subject: [PATCH] fix: give CEF a per-instance cache directory on native runs Only one Strom instance per machine can use `cefsrc` (HTML sources, DSK graphics) when running natively. The second instance fails to start any cefsrc element: GstCefSrc:c: gst_base_src_start (): Failed to start -> HTTP 500 "Element failed to change its state" Chromium keys its process singleton on the cache/profile directory. The strom-full Docker image sets GST_CEF_CACHE_LOCATION=/tmp/cef-cache in its entrypoint, so containers are fine, but native runs never set it and get Chromium's default -- which CEF itself warns about at startup: Please customize CefSettings.root_cache_path for your application. Use of the default value may lead to unintended process singleton behavior. Default the variable to a directory derived from the data directory, so instances with different data directories are isolated. An explicitly configured GST_CEF_CACHE_LOCATION still wins. Measured on macOS arm64, one headless instance starting a cefsrc flow: default (in-memory) 7.1s per-instance, cold 22.9s (one-off, builds an 11MB profile) per-instance, warm 0.9s So the cost is a one-time first-run penalty on a fresh data directory, and repeat starts get faster. Two concurrent instances with distinct data directories both start successfully; forced to share one cache directory, the second still fails as before. --- backend/src/main.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/backend/src/main.rs b/backend/src/main.rs index c21e0d96..8da51afc 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -299,6 +299,26 @@ fn main() -> anyhow::Result<()> { std::process::exit(1); }); + // Give CEF (the `cefsrc` element behind HTML sources and DSK graphics) a + // per-instance cache directory. The strom-full Docker image sets + // GST_CEF_CACHE_LOCATION in its entrypoint, but native runs get Chromium's + // default, which warns + // + // Please customize CefSettings.root_cache_path for your application. Use + // of the default value may lead to unintended process singleton behavior. + // + // and makes Chromium's process singleton shared: a second Strom instance on + // the same machine cannot start any cefsrc element, failing in + // gst_base_src_start() so the flow start returns 500 "Element failed to + // change its state". Deriving the directory from the data directory keeps + // instances isolated, and gives CEF a warm on-disk profile, which also cuts + // repeat flow-start latency. An explicitly configured value always wins. + if std::env::var_os("GST_CEF_CACHE_LOCATION").is_none() { + if let Some(data_dir) = config.flows_path.parent() { + std::env::set_var("GST_CEF_CACHE_LOCATION", data_dir.join("cef-cache")); + } + } + // Initialize logging with optional file output and log level let (log_reload_handle, default_log_filter) = init_logging(config.log_file.as_ref(), config.log_level.as_ref()).unwrap_or_else(|e| {