Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## 2024-05-19 - Missing cache on config files
**Learning:** Config files like `frameworks.yml` are loaded on every function call via `load_framework_registry()` and `get_framework_config()`. This involves file IO and YAML parsing, which is slow if performed repeatedly. `load_model_registry_configs` correctly has `@lru_cache(maxsize=1)` but `load_framework_registry` doesn't.
**Action:** Always check file parsing utilities for proper memoization to avoid redundant disk I/O, using `lru_cache` and `copy.deepcopy()` (if objects are modified downstream) or just `lru_cache` if readonly. In this case, dictionary objects are returned, so apply deepcopy when accessing if they are mutated, or ensure they are treated as immutable.
20 changes: 18 additions & 2 deletions ml_peg/app/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from __future__ import annotations

from collections.abc import Mapping, MutableMapping, Sequence
import copy
from functools import lru_cache
import json
from pathlib import Path
Expand Down Expand Up @@ -891,9 +892,10 @@ def normalize_framework_id(framework_id: str) -> str:
return cleaned


def load_framework_registry() -> dict[str, FrameworkEntry]:
@lru_cache(maxsize=1)
def _load_framework_registry_cached() -> dict[str, FrameworkEntry]:
"""
Load framework badge metadata from ``frameworks.yml``.
Cache inner function for loading framework registry.

Returns
-------
Expand Down Expand Up @@ -947,6 +949,20 @@ def load_framework_registry() -> dict[str, FrameworkEntry]:
return registry


def load_framework_registry() -> dict[str, FrameworkEntry]:
"""
Load framework badge metadata from ``frameworks.yml``.

Returns
-------
dict[str, FrameworkEntry]
Mapping of framework IDs to display configuration.
"""
# Use copy.deepcopy() to prevent unintended cache corruption
# when callers modify the returned nested dictionary
return copy.deepcopy(_load_framework_registry_cached())


def get_framework_config(framework_id: str) -> FrameworkEntry:
"""
Resolve framework metadata for badge and filter rendering.
Expand Down
Loading