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]

Reply via email to