Skip to content

perf: cache /tmp/dash0_env_vars instead of re-reading it on every call - #97

Open
RaphaelManke wants to merge 1 commit into
masterfrom
perf/cache-env-vars-file
Open

perf: cache /tmp/dash0_env_vars instead of re-reading it on every call#97
RaphaelManke wants to merge 1 commit into
masterfrom
perf/cache-env-vars-file

Conversation

@RaphaelManke

Copy link
Copy Markdown
Contributor

Summary

  • try_read_env_from_file() did a blocking std::fs::read_to_string + a fresh serde_json parse on every call, with no caching.
  • get_resources_attributes() calls it from 4 independent sites (metrics_creation.rs, span_creation.rs, span_mutations.rs, exporter.rs), so a single invocation emitting traces, logs, and metrics could trigger this read+parse repeatedly.
  • std::fs is synchronous; calling it from async code blocks the tokio worker thread for the syscall's duration -- on every invocation, for the life of the warm container.
  • The file is written once by opt/shared.sh at cold start and never changes again for the life of the execution environment, so it only needs to be read once per process.

Fix

Cached behind Mutex<Option<Arc<Option<serde_json::Value>>>>, matching the existing shared-state pattern already used in state/global.rs. Added a #[cfg(test)] reset hook and called it at the top of the module's existing tests, since they intentionally rewrite the file mid-suite to exercise different fallback scenarios -- without the reset they'd silently see a previous test's cached content.

Measured

This crate has no [lib] target for a real criterion/divan bench to attach to, so measured in isolation by replicating the exact read+parse call in a throwaway benchmark: 9.4us/call uncached vs. 35ns/call cached -- a 265x difference.

Test plan

  • cargo build --release
  • cargo test --release (325/325 passing, including all 7 otlp::resources::tests::*)
  • Ran the full suite twice to confirm no test-order flakiness from the cache

try_read_env_from_file() did a blocking std::fs::read_to_string plus a
fresh serde_json parse, with no caching, on every call. get_resources_attributes()
calls it from 4 independent sites (metrics_creation.rs, span_creation.rs,
span_mutations.rs, exporter.rs), so a single invocation emitting traces,
logs, and metrics could trigger this file read and parse repeatedly.

std::fs is synchronous; calling it from async code blocks the tokio
worker thread for the syscall's duration, on every invocation, for the
life of the warm container.

The file is written once by opt/shared.sh at cold start and never
changes again for the life of the execution environment, so it only
needs to be read once per process. Cached behind a Mutex<Option<Arc<...>>>
(matching the existing pattern in state/global.rs), with a #[cfg(test)]
reset hook since this module's own tests intentionally rewrite the file
mid-suite to exercise different scenarios.

Measured in isolation (throwaway benchmark replicating the exact read+
parse call, since this crate has no [lib] target for a real criterion/
divan bench to attach to): 9.4us/call uncached vs 35ns/call cached, a
265x difference.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant