Does Groovy's MetaClassRegistry cache return stale GPath results after concurrent ExpandoMetaClass modifications?
0 reputation · 07 May 2020, 04:23 UTC
0 reputation · 07 May 2020, 04:23 UTC
Investigate whether Groovy's internal method cache can return stale GPath evaluation results when ExpandoMetaClass modifications occur concurrently across multiple threads. The goal is to determine if MetaClassRegistry maintains cache consistency without explicit invalidation during runtime metaclass changes.
This question concerns Groovy's documented caching behavior in versions 3.0.x and 4.0.x, specifically around the interaction between concurrent meta-class modifications and GPath expression evaluation. The uncertainty centers on whether the internal method cache automatically invalidates or if stale results persist until manual cache clearing occurs.
Key areas of investigation include: the thread-safety of MetaClassRegistry's internal cache during concurrent modifications, automatic invalidation behavior after ExpandoMetaClass changes, and whether GPath evaluation reads from potentially stale cached method references. Testing should compare behavior between Groovy 3.0.19 and 4.0.15 with identical concurrent modification scenarios.
What specific conditions trigger cache staleness in concurrent scenarios? Does MetaClassRegistry.clearCache() provide sufficient invalidation? Which Groovy versions exhibit different behaviors?
Groovy does not document automatic atomic invalidation of every call-site or GPath cache after concurrent ExpandoMetaClass changes. Stale results are therefore possible until the affected binding is refreshed or cleared. Treat concurrent meta-class mutation as an unsafe configuration pattern unless you add explicit synchronization and cache management.
Confirmed: ExpandoMetaClass supports runtime addition and removal of methods and properties. MetaClassRegistry manages MetaClass instances, and Groovy caches method/property resolution at call sites and invokers. Registry-level cache-clearing operations exist.
Likely explanation: One thread resolves a GPath property or method to a MetaMethod or property binding and caches it. Another thread mutates the ExpandoMetaClass without synchronization. The reader may then use the old binding or miss the new one. The absence of an observed stale result in a single run is not proof of consistency; concurrency bugs are timing-dependent.
clearCache() Does and Does Not DoMetaClassRegistry.clearCache() may invalidate registry-level cached MetaClass and method data. It does not guarantee that in-flight or already-inlined GPath call-site bindings on other threads are discarded, nor does it create a happens-before edge. Pair it with a synchronization barrier and retest.
Internal call-site caching changed across major Groovy versions. Behavior observed on 3.0.19 does not automatically transfer to 4.0.15 or later patch releases. Run the identical scenario on each target version before drawing conclusions.
ExpandoMetaClass. Have one thread repeatedly add, remove, or rename a method or property while other threads evaluate the same GPath expression, covering both property access and method invocation.synchronized barrier and invoke cache clearing after each mutation batch; compare whether candidate staleness disappears.Are the ExpandoMetaClass changes applied at the class level or per instance, and is the GPath expression a property access or a method invocation? That detail determines the invalidation scope and whether a registry-level clear is sufficient.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.