gnodet commented on issue #13519:
URL: https://github.com/apache/maven/issues/13519#issuecomment-6170729998
## Design discussion — cache invalidation strategy
I extracted the `PluginRealmCache.invalidate(Artifact)` change from #13094
into a draft PR #13522 to allow this design conversation before anything lands.
Here is where I think the discussion needs to go.
---
### Scope: all 5 caches, not just one
The staleness problem applies equally to all session-singleton caches:
| Cache | What it holds | Staleness scenario |
|-------|--------------|-------------------|
| `PluginRealmCache` | Plugin classloaders | Plugin rebuilt in workspace |
| `ExtensionRealmCache` | Extension classloaders | Extension rebuilt in
workspace |
| `ProjectRealmCache` | Project classloaders | Project rebuilt in workspace |
| `PluginArtifactsCache` | Resolved plugin artifact lists | New SNAPSHOT in
workspace |
| `MavenMetadataCache` | Repository metadata | Workspace metadata change |
Adding `invalidate()` to just `PluginRealmCache` solves m2e's immediate pain
but leaves the other caches stale. We should decide the right shape for all
five at once.
---
### Option A — Per-cache `invalidate(Artifact)`
Add `default void invalidate(org.apache.maven.api.Artifact artifact)` to
each of the five cache interfaces, with a no-op default.
**Pros:** Incremental, reviewable in isolation, existing implementors are
safe (default no-op), embedders can target only the caches they care about.
**Cons:** Five separate interface changes; callers must know which caches
are relevant; no single coordination point.
**Status:** #13522 is this approach, scoped to `PluginRealmCache` only, as a
starting point.
---
### Option B — Unified `CacheManager` service
Introduce a new `CacheManager` (or `SessionCacheManager`) SPI/service with:
```java
public interface CacheManager {
void invalidate(org.apache.maven.api.Artifact artifact); // cascade to
all caches
void flush(); // full reset
}
```
`DefaultCacheManager` would hold references to all five caches and fan out
the call.
**Pros:** Single call for embedders (they shouldn't have to know Maven's
internal cache topology); clean extension point; maps well to m2e's "rebuild
project → invalidate all" pattern.
**Cons:** New abstraction; more wiring; harder to do incrementally.
---
### Option C — Session-scoped caches
Make all five caches session-scoped instead of singleton. Each embedded
session (e.g., each m2e project refresh) gets fresh caches — no invalidation
API needed.
**Pros:** Eliminates the problem class entirely; consistent with how Maven
CLI works (each run is a fresh process); no new API surface.
**Cons:** Changes lifecycle semantics significantly; may regress performance
in daemon scenarios where cache reuse across builds is intentional; requires
careful threading analysis.
---
### mvnd considerations
Maven Daemon makes this problem concrete in a different way: the JVM stays
alive across builds, so cache staleness is first-class. mvnd already has
`BuildCacheManager` and per-build cache purging logic. A few questions for the
mvnd maintainers:
1. Could mvnd use the same `CacheManager` SPI (Option B) instead of its own
mechanism, if such a thing existed?
2. Would Option C (session-scoped caches) be beneficial for mvnd — i.e.,
does mvnd already want per-build-scoped caches but can't achieve it without
Maven changes?
3. Does mvnd need artifact-level invalidation, or is a full `flush()` per
build sufficient?
---
### Invalidation granularity
Should the parameter be:
- `Artifact` — precise, but callers must resolve coordinates
- `Plugin` — natural for plugin-realm invalidation, less so for metadata
- `Project` — matches m2e's "invalidate everything for this project" mental
model
- No parameter / `flush()` — simplest, but too coarse for daemon scenarios
My current preference is `Artifact` for precision, with `flush()` as a
separate method for the full-reset case.
---
### Recommendation
I'd suggest:
1. Merge #13094 (WorkspaceReader SPI) independently — it stands on its own
and has no design ambiguity.
2. Keep #13522 as a draft for design validation. If Option A (per-cache)
wins the discussion, expand it to cover all 5 caches before merging. If Option
B wins, replace it with a `CacheManager` design.
3. Get input from the mvnd and m2e communities before committing to any
shape.
Happy to prototype Option B alongside the existing Option A draft if that
helps the comparison.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]