Skip to content

[Bug]: In-memory cache in data_loader.py is defined but never used #271

Description

@anshul23102

Describe the bug

utils/data_loader.py declares _projects_cache = None and a clear_cache() helper, but load_all_projects() never reads or writes that variable. As a result, every call to load_all_projects() opens and parses projects.json from disk, even when the data has not changed.

Every HTTP request that touches /, /api/recommend, or /project/<id> triggers at least one (often two or three) redundant file reads.

Current code (utils/data_loader.py)

_projects_cache = None          # defined but never populated

def load_all_projects():
    with open(DATA_FILE, "r", encoding="utf-8") as f:   # reads disk on every call
        return json.load(f)

def clear_cache():
    global _projects_cache
    _projects_cache = None      # clears a cache that never fills

Expected behaviour

projects.json is read once on the first call; every subsequent call returns the cached list. clear_cache() resets it (used in tests).

Proposed fix

Implement a thread-safe double-checked locking pattern using threading.Lock:

_projects_cache = None
_cache_lock = threading.Lock()

def load_all_projects():
    global _projects_cache
    if _projects_cache is not None:
        return _projects_cache
    with _cache_lock:
        if _projects_cache is None:
            with open(DATA_FILE, "r", encoding="utf-8") as f:
                _projects_cache = json.load(f)
    return _projects_cache

This ensures the file is read exactly once even under concurrent requests.


I am a GSSoC 2026 contributor and would like to work on this fix. Could you please assign this issue to me?

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions