From 3d888d7b070043cefbc442b257825f4a948f7d2a Mon Sep 17 00:00:00 2001 From: MikaAK Date: Sun, 3 May 2026 19:10:29 -0700 Subject: [PATCH 1/2] perf(sandbox): make register_caches sleep configurable Cache.SandboxRegistry.register_caches/2 sleeps Process.sleep(50) after each Registry.register call to give the entry time to propagate. With N caches registered per test (common in apps with many cache modules), this becomes ~N * 50ms of fixed overhead per test setup. Read the value via Application.compile_env(:elixir_cache, :sandbox_sleep_ms, 50). Default is unchanged at 50ms (backward compatible). Test suites can opt in to a faster value (commonly 0): # config/test.exs config :elixir_cache, :sandbox_sleep_ms, 0 In a downstream umbrella with several cache apps, setting this to 0 saved ~1.7s across last_symbol_price_cache (10 tests x 102ms), open_interest_cache (10 x 51ms), options_contract_expiry_cache (3 x 51ms), and active_symbols_cache (4 x 51ms). --- CHANGELOG.md | 6 ++++++ lib/cache/sandbox_registry.ex | 2 +- mix.exs | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ee6cbb..fbd222a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 0.4.9 + +## Performance + +- perf(sandbox): make `Cache.SandboxRegistry.register_caches/2` post-register sleep configurable via `Application.compile_env(:elixir_cache, :sandbox_sleep_ms, 50)`. Default is unchanged (50 ms). Test suites that don't need the sleep can set it to 0 to save ~50 ms per cache registered per test — material on apps with many cache modules. + # 0.4.8 ## Bug Fixes diff --git a/lib/cache/sandbox_registry.ex b/lib/cache/sandbox_registry.ex index fe57f29..95a09d7 100644 --- a/lib/cache/sandbox_registry.ex +++ b/lib/cache/sandbox_registry.ex @@ -5,7 +5,7 @@ defmodule Cache.SandboxRegistry do More details soon... """ - @sleep_for_sync 50 + @sleep_for_sync Application.compile_env(:elixir_cache, :sandbox_sleep_ms, 50) @registry :elixir_cache_sandbox @keys :duplicate diff --git a/mix.exs b/mix.exs index 618d38e..6f638d0 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule ElixirCache.MixProject do def project do [ app: :elixir_cache, - version: "0.4.8", + version: "0.4.9", elixir: "~> 1.11", start_permanent: Mix.env() == :prod, description: From 97183c2d41a206f969117840cd73f5e5f40b989c Mon Sep 17 00:00:00 2001 From: MikaAK Date: Sun, 3 May 2026 19:25:20 -0700 Subject: [PATCH 2/2] refactor: route sandbox_sleep_ms through Cache.Config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per the request_cache_plug Config module pattern. Adds lib/cache/config.ex with `Cache.Config.sandbox_sleep_ms/0` and switches SandboxRegistry from a compile-time module attribute reading Application.compile_env to a runtime call to the accessor. Two reasons the runtime form is better here: 1. Process.sleep is already runtime-bound; the extra Application.get_env call is a no-op compared to the actual sleep. 2. Future config knobs (TTL defaults, log levels, etc.) can land on the same module, making the contract for downstream apps obvious — they `config :elixir_cache, ...` and read via `Cache.Config`. No behavior change vs. the previous commit on this branch — default still 50 ms, override via the same `config :elixir_cache, :sandbox_sleep_ms, N` key. --- CHANGELOG.md | 2 +- lib/cache/config.ex | 9 +++++++++ lib/cache/sandbox_registry.ex | 3 +-- 3 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 lib/cache/config.ex diff --git a/CHANGELOG.md b/CHANGELOG.md index fbd222a..51ffc2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## Performance -- perf(sandbox): make `Cache.SandboxRegistry.register_caches/2` post-register sleep configurable via `Application.compile_env(:elixir_cache, :sandbox_sleep_ms, 50)`. Default is unchanged (50 ms). Test suites that don't need the sleep can set it to 0 to save ~50 ms per cache registered per test — material on apps with many cache modules. +- perf(sandbox): make `Cache.SandboxRegistry.register_caches/2` post-register sleep configurable via `Cache.Config.sandbox_sleep_ms/0` (`config :elixir_cache, :sandbox_sleep_ms, 50`). Default is unchanged (50 ms). Test suites that don't need the sleep can set it to `0` in `config/test.exs` to save ~50 ms per cache registered per test — material on apps with many cache modules. # 0.4.8 diff --git a/lib/cache/config.ex b/lib/cache/config.ex new file mode 100644 index 0000000..c73c30a --- /dev/null +++ b/lib/cache/config.ex @@ -0,0 +1,9 @@ +defmodule Cache.Config do + @moduledoc false + + @app :elixir_cache + + def sandbox_sleep_ms do + Application.get_env(@app, :sandbox_sleep_ms, 50) + end +end diff --git a/lib/cache/sandbox_registry.ex b/lib/cache/sandbox_registry.ex index 95a09d7..5674213 100644 --- a/lib/cache/sandbox_registry.ex +++ b/lib/cache/sandbox_registry.ex @@ -5,7 +5,6 @@ defmodule Cache.SandboxRegistry do More details soon... """ - @sleep_for_sync Application.compile_env(:elixir_cache, :sandbox_sleep_ms, 50) @registry :elixir_cache_sandbox @keys :duplicate @@ -38,7 +37,7 @@ defmodule Cache.SandboxRegistry do {:error, :registry_not_started} -> raise_not_started!() end - Process.sleep(@sleep_for_sync) + Process.sleep(Cache.Config.sandbox_sleep_ms()) res end