Skip to content

Conversation

knguyen1
Copy link
Contributor

Summary

  • This is a…
    • Bug fix
    • Feature addition
    • Refactoring
    • Minor / simple change (like a typo)
    • Other
  • Describe this change in 1-2 sentences:
    Fix stale custom column values and incompatible sort keys by adding targeted cache invalidation and safe re-sorting.

Problem

  • Custom column values remained stale after tag changes.

  • Editing sort order could leave incompatible sort keys cached, causing incorrect sorting.

  • JIRA ticket (optional): PICARD-XXX

Solution

  • Introduce CacheInvalidatable protocol; implement invalidate() in ChainedValueProvider and CachedSortAdapter.
  • Add CustomColumn.invalidate_cache() and invoke it per-item in TreeItem.update_colums_text.
  • On header updates, invalidate provider caches, clear all item _sortkeys, refresh data, and trigger resort (BaseTreeView).
  • Replace broad try...except...pass with explicit handling or contextlib.suppress per project guidelines.

Action

Additional actions required:

  • Update Picard documentation (please include a reference to this PR)
  • Other (please specify below)

@zas zas requested review from phw and zas and removed request for zas September 22, 2025 13:27
Copy link
Member

@phw phw left a comment

Choose a reason for hiding this comment

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

Code looks good to me. I'll want to test run this before merging, though.

Copy link
Member

@phw phw left a comment

Choose a reason for hiding this comment

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

I tested and it works unless a sort adapter is involved.

I think _AdapterBase should implement invalidate somewhat like this:

    def invalidate(self, obj: Item | None = None) -> None:
        if isinstance(self._base, CacheInvalidatable):
            self._base.invalidate(obj)

Otherwise ChainedValueProvider.invalidate never gets called.

I also don't fully understand the role of the CachedSortAdapter, it is currently unused. Do we actually need it, as the value provider already handles caching? Or should all sort adapters be CachedSortAdapter?

@knguyen1
Copy link
Contributor Author

Do we actually need it

Not for the default path. Providers already cache evaluations; Python’s sorted(key=...) calls the key once per element per sort. Most adapters are cheap transforms.

Should all sort adapters be CachedSortAdapter?

No. Making all adapters cached adds memory and invalidation complexity and risks stale keys unless UI consistently calls invalidate. Keep other adapters stateless.

It's an opt-in utility. I recommend keeping it (it's only a small class with some tests).

Use CachedSortAdapter selectively when:

  • You supply a custom, potentially expensive key_func or you need its normalization to avoid mixed-type comparisons.
  • The base provider doesn’t cache but the sort key is expensive to compute.
  • You need fine-grained key invalidation independent from value-cache policy.

If you wrap a provider with it, CustomColumn.invalidate_cache(...) will delegate to the adapter if present, so invalidation still works end-to-end.

Copy link
Member

@phw phw left a comment

Choose a reason for hiding this comment

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

Thanks for the changes and the explanation. Works well in my testing and code looks good.

@phw phw merged commit 63ec82b into metabrainz:master Sep 28, 2025
45 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants