Merge pull request 'vars/list: reduce cache misses to 1' (#5331) from dave into main

Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/5331
This commit is contained in:
DavHau
2025-10-01 05:52:55 +00:00
3 changed files with 41 additions and 4 deletions

View File

@@ -1263,6 +1263,41 @@ def test_share_mode_switch_regenerates_secret(
)
@pytest.mark.with_core
def test_cache_misses_for_vars_list(
monkeypatch: pytest.MonkeyPatch,
flake: ClanFlake,
) -> None:
"""Test that listing vars results in exactly one cache miss."""
config = flake.machines["my_machine"]
config["nixpkgs"]["hostPlatform"] = "x86_64-linux"
# Set up a simple generator
my_generator = config["clan"]["core"]["vars"]["generators"]["my_generator"]
my_generator["files"]["my_value"]["secret"] = False
my_generator["script"] = 'echo -n "test" > "$out"/my_value'
flake.refresh()
monkeypatch.chdir(flake.path)
# # Generate the vars first
# cli.run(["vars", "generate", "--flake", str(flake.path), "my_machine"])
# Create a fresh machine object to ensure clean cache state
machine = Machine(name="my_machine", flake=Flake(str(flake.path)))
# Record initial cache misses
initial_cache_misses = machine.flake._cache_misses
# List all vars - this should result in exactly one cache miss
stringify_all_vars(machine)
# Assert we had exactly one cache miss for the efficient lookup
assert machine.flake._cache_misses == initial_cache_misses + 1, (
f"Expected exactly 1 cache miss for vars list, got {machine.flake._cache_misses - initial_cache_misses}"
)
@pytest.mark.with_core
def test_dynamic_invalidation(
monkeypatch: pytest.MonkeyPatch,

View File

@@ -23,8 +23,6 @@ def get_machine_vars(machine: Machine) -> list[Var]:
"""
# TODO: We dont have machine level store / this granularity yet
# We should move the store definition to the flake, as there can be only one store per clan
pub_store = machine.public_vars_store
sec_store = machine.secret_vars_store
all_vars = []
@@ -34,9 +32,9 @@ def get_machine_vars(machine: Machine) -> list[Var]:
for generator in generators:
for var in generator.files:
if var.secret:
var.store(sec_store)
var.store(machine.secret_vars_store)
else:
var.store(pub_store)
var.store(machine.public_vars_store)
var.generator(generator)
all_vars.append(var)
return all_vars

View File

@@ -792,6 +792,7 @@ class Flake:
_cache: FlakeCache | None = field(init=False, default=None)
_path: Path | None = field(init=False, default=None)
_is_local: bool | None = field(init=False, default=None)
_cache_misses: int = field(init=False, default=0)
@classmethod
def from_json(
@@ -1062,6 +1063,8 @@ class Flake:
]
if not_fetched_selectors:
# Increment cache miss counter for each selector that wasn't cached
self._cache_misses += 1
self.get_from_nix(not_fetched_selectors)
def select(
@@ -1087,6 +1090,7 @@ class Flake:
if not self._cache.is_cached(selector):
log.debug(f"(cached) $ clan select {shlex.quote(selector)}")
log.debug(f"Cache miss for {selector}")
self._cache_misses += 1
self.get_from_nix([selector])
else:
log.debug(f"$ clan select {shlex.quote(selector)}")