Skip to content

Per-Version Index Cache in ~/.cabal directory #7502

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
gbaz opened this issue Aug 2, 2021 · 7 comments · May be fixed by #10848
Open

Per-Version Index Cache in ~/.cabal directory #7502

gbaz opened this issue Aug 2, 2021 · 7 comments · May be fixed by #10848

Comments

@gbaz
Copy link
Collaborator

gbaz commented Aug 2, 2021

Switching between cabal install versions can occur either when developing cabal, or when using nix-shells that bring different versions into scope, among other reasons.

Each time you switch versions, you get Warning: Parsing the index cache failed and it needs to regenerate the index cache.

This can be tedious and time consuming.

I suggest that cabal store its index cache per-cabal-version rather than always in the same spot, thus helping to more frequently avoid this issue.

@Mikolaj
Copy link
Member

Mikolaj commented Aug 2, 2021

No counterindication, as far as I can see.

@ptkato
Copy link
Collaborator

ptkato commented Aug 2, 2021

That would be an welcome change, specially when developing for cabal, since there are usually multiple cabals involved in the whole compile/run thingy.

@phadej
Copy link
Collaborator

phadej commented Aug 3, 2021

This was discussed and it is not trivial. The cabal update command wouldn't update the cache files of other cabal-install versions. That is probably not a problem for Hackage index as it's append only (so the old index cache will just not see new stuff), but e.g. with head.hackage index (which is competely overwritten) very weird things will happen.

Please outline how you would prevent cache corruption.

@gbaz
Copy link
Collaborator Author

gbaz commented Aug 3, 2021

Good point about cabal update! Does it do a full rewrite of the index cache file or is it an in-place update?

@gbaz
Copy link
Collaborator Author

gbaz commented Aug 3, 2021

The obvious thing to do is to just have update remove all versions of the index cache, and let them be generated as necessary on demand. I think this would be pretty seamless...

@andreasabel
Copy link
Member

I think this issue is important to fix, because having several versions of cabal-install around is the advice when one still relies on sandboxes.

@mpickering
Copy link
Collaborator

I think that a suitable invalidation strategy is that if the cacheFile is older than the indexFile then you need to regenerate the cache. Then if another version of cabal-install updates the index file, you will see your cache is too old and regenerate the cache when necessary.

This check if helpfully already implemented in whenCacheOutOfDate but it is not used in the readIndexCache function. Therefore the implementation plan is to modify readIndexCache so that it checks two things

  1. The cache is up-to-date, (older than the indexFile)
  2. It can decode the cache, and regenerate it if it can't.

Situation 2 shouldn't happen anymore (unless you are developing cabal-install) since there will be a per-version cache, each cabal-install will

Then to consider backwards compatibility.

  • A newer cabal-install calls cabal update, the tar.gz is updated. We need to invalidate the cache for the older cabal-install.
  • Older cabal-installs don't check the cache for up-to-dateness when reading it.
  • Therefore, implement a backwards compatible invalidation mechanism.

When the new cabal-install runs cabal update, if there are any old-style caches for that repo, then invalidate them by replacing them with an empty file.

To summarise:

  • Old cabal-install runs cabal-update, new cabal-install realises that the cache it has is too old, regenerates.
  • New cabal-install runs cabal-update, dirties the old cache file, old cabal-install tries to read the cache file, it fails and regenerates the cache.

mpickering added a commit that referenced this issue Mar 24, 2025
cabal-install will now use a version suffixed cache file for the index
state.

If you are regularly changing between cabal-install versions, this will
be less annoying as you won't have to regenerate the cache each time you
switch project.

There is one tricky part of the implementation. If you update the index
with a newer cabal-install, then the old-style cabal-install caches are
invalidated by replacing them with an empty file.
This is because in cabal-install (until this commit), the freshness of
the cache was now checked by `readIndexCache`.

If you update with an older `cabal-install` then the freshness check
will see the cache for your new cabal-install is older than the index,
and update it.

Fixes #7502
mpickering added a commit that referenced this issue Mar 24, 2025
cabal-install will now use a version suffixed cache file for the index
state.

If you are regularly changing between cabal-install versions, this will
be less annoying as you won't have to regenerate the cache each time you
switch project.

There is one tricky part of the implementation. If you update the index
with a newer cabal-install, then the old-style cabal-install caches are
invalidated by replacing them with an empty file.
This is because in cabal-install (until this commit), the freshness of
the cache was now checked by `readIndexCache`.

If you update with an older `cabal-install` then the freshness check
will see the cache for your new cabal-install is older than the index,
and update it.

Fixes #7502
@mpickering mpickering linked a pull request Mar 24, 2025 that will close this issue
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants