Skip to content

cacheHits & cacheMisses in DefaultCacheStatistics.CompensatingCounters are duplicated by multiple clear() #3302

@jdbeutel

Description

@jdbeutel

DefaultCacheStatistics.CompensatingCounters.snapshot() duplicates the cacheHits and cacheMisses. So, from the second time that DefaultCacheStatistics.clear() is called, they double, at least. After that, getCacheHits() and getCacheMisses() results would be negative, if normalize() didn't limit them to 0, until getHits() and getMisses() double, at least.

This issue can be reproduced by simply adding a third innerClear() call to testClearingStats() in CacheCalculationTest and JCacheCalculationTest, which then fail like this:

[Test worker] ERROR org.ehcache.integration.statistics.JCacheCalculationTest - Counters at time of assertion:  (H=0 M=0 P=3 R=2 Ev=0 Ex=0)
org.assertj.core.api.SoftAssertionError: 
The following 2 assertions failed:
1) [Hits] expected:<[1]L> but was:<[0]L>
2) [Misses] expected:<[4]L> but was:<[0]L>

Not to dictate a solution, but to help explain this issue, the following change avoids the above test failures:

     CompensatingCounters snapshot(DefaultCacheStatistics statistics) {
       return new CompensatingCounters(
-        cacheHits + statistics.getHits(),
-        cacheMisses + statistics.getMisses(),
+        cacheHits + statistics.getCacheHits(),
+        cacheMisses + statistics.getCacheMisses(),
         cacheGets + statistics.getCacheGets(),
         cachePuts + statistics.getCachePuts(),
         cacheRemovals + statistics.getCacheRemovals());

Or, I think the following change would work as well:

     CompensatingCounters snapshot(DefaultCacheStatistics statistics) {
       return new CompensatingCounters(
-        cacheHits + statistics.getHits(),
-        cacheMisses + statistics.getMisses(),
+        statistics.getHits(),
+        statistics.getMisses(),
         cacheGets + statistics.getCacheGets(),
         cachePuts + statistics.getCachePuts(),
         cacheRemovals + statistics.getCacheRemovals());

It looks like this issue was introduced about 9 years ago, by a commit to stop bulks from being calculated twice.

DefaultCacheStatistics was moved from org.ehcache.impl.internal.statistics to org.ehcache.core.internal.statistics. Then, in 2020, it was copied to org.ehcache.management.statistics, to "truly hide the statistics library uses". It looks like both copies have this issue, although the latter isn't tested directly?

I emailed ehcache-dev@googlegroups.com about this issue a couple days ago, but haven't seen a response yet, so I'm submitting this issue now, to get an identification for it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions