Pluggable simulator policies: register external Policy classes without editing Registry.java #1961
Replies: 1 comment
-
|
Hi @yanivholder2! My main concern is keeping it simple and approachable. Other than myself, the simulator is used by graduate students conducting research or senior developers with little Java experience implementing caches in their preferred language. Therefore less magic to understand and an obvious setup is ideal. The policies are each self-contained attempts to be a reference algorithm if someone wanted to implement it for their own caching library. As these users have a short-term interest their changes don't tend to be upstreamed, as it's effort and it shifts the maintenance burden onto me. With that in mind, forking tends to be necessary anyway. If a researcher is investigating a new idea it likely relies on a different type of signal that is not modeled currently, such as the miss penalty (aka. latency, cost) or prefetching. Then they need to modify the I would lean towards (A) as well since it's less magical, solves your problem, is simple. Your code snippet could be simplified to |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi @ben-manes — floating this as a question before any PR. Would you accept a small extension point letting the simulator load
Policyimplementations that live outside the caffeine source tree, and if so, do you have a preferred mechanism? Happy to implement and sign the CLA.Context
We run a research framework that grades cache-replacement policies on hit-rate using caffeine's trace simulator as the ground-truth oracle. Our candidate caches are implemented in Rust and bridged to the simulator via JNI — each is a
Policysubclass that loads a native library and forwardsrecord/stats.Today the only way to wire a new policy into the simulator is to edit
Registry.buildRegistry()to add aregister*()call. That forces downstream projects to maintain a fork and rebase as the registration chain evolves. Everything else we need is already drop-in: our policy classes live in new packages (no file conflicts) and all settings are passed as-Doverrides at runtime.What's currently closed
Registry.buildRegistry()hard-codes the set ofregister*()calls;registerMany(...)stores factories in the privatefactoriesmap keyed by the@PolicySpecname.policies()resolves names from settings against that map, erroring if absent.ServiceLoader/META-INF/services, no classpath scanning, no config key for external policies — so there's no public hook to extendfactories.The
Policycontract itself is already self-describing (@PolicySpeccarriesname()+characteristics(); policies construct from aConfig), so an external class needs no new contract — just a discovery path.Two candidate mechanisms (~30 LOC either way, backwards-compatible, default off)
A. Config + reflection. A
caffeine.simulator.external-policies = [ "<fqcn>", … ]list (default empty inreference.conf, read byBasicSettings), loaded by aregisterExternal()called at the end ofbuildRegistry():Selection stays by
@PolicySpecname. Fits the existing Typesafe-Config style; a bad FQCN fails loudly at startup, consistent with unknown-policy errors inpolicies().B.
ServiceLoader. Discover viaServiceLoader.load(Policy.class)and register those annotated with@PolicySpec. Zero runtime config; most "standard Java." Cost to consumers: shipping aMETA-INF/servicesentry.Why we lean toward A
We pass all simulator settings as
-Doverrides, so a config list means the policy FQCN comes straight from our runner with nothing assembled inside the caffeine checkout.ServiceLoaderwould require generating/merging aMETA-INF/servicesfile in the clone — the one "edit a file in caffeine" step we're trying to remove. That said, we're glad to implement whichever you prefer.Scope / compatibility
Default empty → existing runs byte-for-byte unaffected. No new dependencies (stdlib reflection or
ServiceLoader). TouchesRegistry,BasicSettings,reference.conf(A) or addsServiceLoaderdiscovery (B).Beta Was this translation helpful? Give feedback.
All reactions