mpfaffenberger / mpfaffenberger/code_puppy
config.get_value() re-reads and re-parses puppy.cfg from disk on every call — hot-path I/O churn + write race
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 814
- Forks
- 278
- Avg merge
- 2d 5h
- Merged PRs (30d)
- 76
Description
Problem
code_puppy/config.py lines 252-256:
def get_value(key: str):
config = configparser.ConfigParser()
config.read(CONFIG_FILE)
val = config.get(DEFAULT_SECTION, key, fallback=None)
return val
Every one of the ~60 config getters funnels through this, and each call constructs a fresh ConfigParser and re-reads/parses the cfg file from disk. Several of these getters sit on hot paths:
get_yolo_mode()andmodel_supports_setting()are called frommake_model_settings()on every model construction.get_effective_model_settings()->get_all_model_settings()does another full file read+parse, plusget_temperature()->get_value()again -- 3+ file parses per model-settings resolution.- The file's own comment at line ~200 admits
get_global_model_name()"happens a LOT" -- which is why a_SESSION_MODELcache was bolted on for that one key, but the underlying problem remains for everything else.
Why it matters
Dozens of redundant open()+parse syscalls per agent turn. The same pattern also creates a read-modify-write race in set_config_value()/set_model_name() (read file -> mutate -> rewrite whole file): two concurrent writers on different keys can silently drop one write.
Suggested fix
Cache the parsed config with mtime invalidation:
_cfg_cache: tuple[int, configparser.ConfigParser] | None = None
def _load_config() -> configparser.ConfigParser:
global _cfg_cache
try:
mtime = os.stat(CONFIG_FILE).st_mtime_ns
except OSError:
mtime = -1
if _cfg_cache is None or _cfg_cache[0] != mtime:
cfg = configparser.ConfigParser()
cfg.read(CONFIG_FILE)
_cfg_cache = (mtime, cfg)
return _cfg_cache[1]
def get_value(key: str) -> Optional[str]:
return _load_config().get(DEFAULT_SECTION, key, fallback=None)
Writers (set_config_value, reset_value, clear_model_settings, set_model_name) should invalidate the cache after writing, ideally behind a single threading.Lock to also fix the read-modify-write race.
Filed by Zen Reviewer A (code-puppy-60635a)
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read code_puppy/config.py around get_value, set_config_value, reset_value, clear_model_settings, and set_model_name. Trace how reads and read-modify-write updates interact, then implement cache invalidation and synchronization so repeated getters avoid redundant parsing and concurrent writers do not lose updates.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- performance, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100