Skip to content

fix: strip mirror file contents in MinerEvaluationCache - #824

Merged
anderdc merged 3 commits into
entrius:testfrom
carlos4s:fix/mirror-cache-memory-leak
May 1, 2026
Merged

fix: strip mirror file contents in MinerEvaluationCache#824
anderdc merged 3 commits into
entrius:testfrom
carlos4s:fix/mirror-cache-memory-leak

Conversation

@carlos4s

@carlos4s carlos4s commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

Summary

MinerEvaluationCache got shallow-copy helpers in #786, but they only cover the legacy PullRequest lists. The three mirror lists (mirror_merged_prs, mirror_open_prs, mirror_closed_prs) still get shared by reference, which causes two real problems:

  • Memory: cached evaluations keep ScoredMirrorPR.files[*].head_content and base_content (whole head/base file blobs). Cache memory grows with every mirror-scored PR and never shrinks ([Bug]:MinerEvaluationCache doesn't strip mirror file contents — unbounded memory growth #823).
  • Aliasing: mutations on the source eval after store() leak into the cache, and back-to-back get() calls hand back the same ScoredMirrorPR / MirrorPullRequest / MirrorLinkedIssue / MirrorLabel objects.

This PR extends the same shallow-copy strategy from #786 to mirror PRs, via four small private helpers that mirror the existing _pr_for_cache / _pr_with_fresh_issues pair:

  • _build_cache_entry: drop ScoredMirrorPR.files and shallow-copy the nested MirrorPullRequest (review_summary, labels, linked_issues + each linked issue's labels).
  • _isolate_for_downstream: same nested-metadata copy on the way out, so successive get() calls return fully independent snapshots.

The cache-fallback path only runs issue competitions and issue discovery scoring, neither of which reads file contents — so dropping files outright is enough, no need to keep stripped MirrorFile placeholders.

Related Issues

Closes #823

Type of Change

  • Bug fix
  • New feature
  • Refactor
  • Documentation
  • Other (describe below)

Testing

  • Tests added/updated
  • Manually tested

Three new tests in tests/validator/test_validator_cache_fallback.py::TestMirrorCacheIsolation, one per invariant:

  • test_cache_drops_mirror_files_without_mutating_sourcefiles is None on the cached copy across all three mirror buckets, and the source eval is untouched.
  • test_store_isolates_cached_mirror_metadata_from_source_mutations — mutating source.mirror_merged_prs[i].pr.{title, review_summary, labels, linked_issues} after store() does not affect the cached copy.
  • test_get_returns_isolated_mirror_metadata — two consecutive get() calls return independent snapshots.
$ uv run pytest tests/validator/test_validator_cache_fallback.py -v
9 passed

$ uv run pytest tests/
all green

$ uv run ruff check && uv run ruff format --check
clean

$ uv run pyright gittensor/classes.py tests/validator/test_validator_cache_fallback.py
0 errors

Checklist

  • Code follows project style guidelines
  • Self-review completed
  • Changes are documented (if applicable)

@xiao-xiao-mao xiao-xiao-mao Bot added the bug Something isn't working label Apr 27, 2026
@carlos4s
carlos4s force-pushed the fix/mirror-cache-memory-leak branch 2 times, most recently from 7cd1d27 to 2989ad6 Compare April 29, 2026 22:41
@carlos4s carlos4s changed the title fix: strip mirror file contents in MinerEvaluationCache lightweight copy fix: strip mirror file contents in MinerEvaluationCache Apr 29, 2026
@carlos4s

Copy link
Copy Markdown
Contributor Author

@anderdc Please review this PR. I'd appreciate any feedbacks. Thanks

@anderdc anderdc left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scope this down to the actual leak. The file-strip change in _build_cache_entry plus a _scored_mirror_pr_for_cache helper that nulls files is all #823 asks for.

Drop _scored_mirror_pr_with_fresh_pr, _mirror_pr_with_fresh_metadata, _mirror_linked_issue_with_fresh_labels, the _isolate_for_downstream mirror branch, and the two metadata-isolation tests (test_store_isolates_cached_mirror_metadata_from_source_mutations, test_get_returns_isolated_mirror_metadata) — those guard against mutations no caller on the cache-fallback path actually makes. The legacy _pr_with_fresh_issues deliberately only deep-copies issues for the same reason; see the comment at classes.py:723-725 ("PR metadata is read-only on the cache-fallback path, so we can share it"). The mirror path feeds the same downstream (issue competitions + issue discovery), so the same logic applies.

Keep test_cache_drops_mirror_files_without_mutating_source — that one matches the actual issue invariant.

If aliasing on metadata ever becomes a real concern, land it in its own PR with the offending caller cited.

@carlos4s
carlos4s force-pushed the fix/mirror-cache-memory-leak branch from 4334a38 to 2dd3fad Compare May 1, 2026 19:40
@carlos4s

carlos4s commented May 1, 2026

Copy link
Copy Markdown
Contributor Author

@anderdc pushed the update. plz review again.

@anderdc
anderdc merged commit ffbf2de into entrius:test May 1, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]:MinerEvaluationCache doesn't strip mirror file contents — unbounded memory growth

2 participants