Skip to content

loading: add JULIA_PRECOMPILE_CACHE_KEY to cache file names - #63294

Open
IanButterworth wants to merge 1 commit into
JuliaLang:masterfrom
IanButterworth:ib/compilecache-hostname
Open

IanButterworth wants to merge 1 commit into
JuliaLang:masterfrom
IanButterworth:ib/compilecache-hostname

Conversation

@IanButterworth

@IanButterworth IanButterworth commented Sep 20, 2026

Copy link
Copy Markdown
Member

Fixes #63268

Claude:


Narrow alternative to #63293. Cache file names are keyed on the active project path, so containers that share a depot but mount different projects at the same path (say /work) give incompatible caches the same name and overwrite each other: alternating loads recompile every time, and concurrent precompilation fails with "Required dependency ... failed to load from a cache file" or "Module ... is missing from the cache".

Change

  • New JULIA_PRECOMPILE_CACHE_KEY: if set, its value is mixed into the cache file name on top of the existing inputs (project path, preferences, flags, cpu target, julia binary and sysimage). It adds uniqueness; it does not replace any of them. The LRU and cleanup are untouched. Documented in the manual.
  • The pidfile path leaves the key out, as it already leaves out the project and preferences: the lock is per package, taken before the file name is known, and a waiter re-checks for a usable cache once it gets the lock. Apps with different keys but the same package version therefore compile it once and share the result rather than twice in parallel.

What it does and does not do

  • Loading reads file contents rather than names. A compatible cache written under one key is reused under any other, and changing the key does not trigger recompilation; it only affects which file a compile writes.
  • Nothing changes unless the variable is set. Container runners give each app a stable, distinct key; apps with the same key and project path still collide, as before.
  • This does not fix every shared-depot collision, only the same-path one the reporter hit.

Tests

In test/precompile.jl, using the key to stand in for separate apps: incompatible versions at one project path written under different keys coexist with their dependents and are reused when alternating (fails on nightly: the second write overwrites the first); a compatible cache is reused under another key without a new file; a rebuild under the same key and project replaces the same file; projects with different preferences keep separate files; unset/empty/set semantics and pidfile independence. precompile and loading test files pass locally. The two-container case itself was not run; it needs Linux mount namespaces.

@IanButterworth IanButterworth added packages Package management and loading compiler:precompilation Precompilation of modules labels Sep 20, 2026
@DilumAluthge

Copy link
Copy Markdown
Member

The hostname is mixed into the cache file name

How would this work on an HPC cluster with multiple head nodes and multiple compute nodes, but a single filesystem mounted across all nodes?

@IanButterworth

Copy link
Copy Markdown
Member Author

The first one to precompile it would give it a name based on those keys, then the others would use it.

The filename doesn't restrict cache usage.

@IanButterworth
IanButterworth marked this pull request as ready for review September 20, 2026 19:02
@IanButterworth

Copy link
Copy Markdown
Member Author

I guess a worry with this is that the hostname could be too volatile especially on laptops as it can be dependent on network characteristics, which would make a single project use up more cache slots.

@IanButterworth
IanButterworth force-pushed the ib/compilecache-hostname branch from 8f1ca12 to b6156a9 Compare September 21, 2026 14:41
@IanButterworth IanButterworth changed the title loading: add the hostname and JULIA_PRECOMPILE_CACHE_KEY to cache file names loading: add JULIA_PRECOMPILE_CACHE_KEY to cache file names Sep 21, 2026
Cache file names are keyed on the active project path, so containers that
share a depot but mount different projects at the same path (say `/work`) give
incompatible caches the same name and overwrite each other: alternating loads
recompile every time and concurrent precompilation fails with "Required
dependency ... failed to load from a cache file" or "Module ... is missing from
the cache" when a file is replaced between the staleness check and the load.

Mix the value of `JULIA_PRECOMPILE_CACHE_KEY` into the name when it is set, on
top of the existing project path, preferences, flags and binary inputs rather
than in place of any of them, so a runner can give each app a stable, distinct
key. Loading reads file contents rather than names, so a compatible cache
written under one key is still reused under another, and a changed key only
takes another file when a compile actually happens. The pidfile path leaves
the key out, so locking stays shared. Apps with the same key and project path
collide as before.

Fixes JuliaLang#63268

Assisted-by: Claude Code (Opus 5)
@IanButterworth

Copy link
Copy Markdown
Member Author

@KristofferC I'm not sure if there's a cleaner fix we can backport without adding an env var, perhaps this is acceptable?

@IanButterworth IanButterworth added the backport 1.13 Change should be backported to release-1.13 label Sep 21, 2026
Comment on lines +198 to +205
If set, an extra string mixed into the name of precompile cache files, on top of what
already distinguishes them (the project path, the preferences, the compiler flags and the
julia binary). It does not replace any of those. The name only decides which existing
file a compile overwrites; loading checks file contents, so a cache written under one
value is still reused under another. Setting a stable, distinct value per app lets
containers that share a depot but mount different projects at the same path (say `/work`)
keep their caches from overwriting each other. Apps with the same key and project path
still collide.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This feels like it should be rewritten by a human. It currently seems to assume you are a robot who has read exactly how loading.jl is implemented.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Happy to polish this if the approach sounds ok?

@vtjnash vtjnash Sep 21, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The approach seems a bit bad, but I'm not sure what else you'd do. It doesn't hurt anything, just an extra 200 lines of code (mostly tests)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think these might be a better approach #63310 JuliaLang/Pkg.jl#4824

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport 1.13 Change should be backported to release-1.13 compiler:precompilation Precompilation of modules packages Package management and loading

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: cache file name keyed on project path collides across containers sharing a depot

3 participants