ehcache / ehcache3

Ehcache 3.x line
http://www.ehcache.org
Apache License 2.0
2k stars 578 forks source link

Mutations of an offheap or disk cache with a loader/writer can misreport statistics. #1056

Open chrisdennis opened 8 years ago

chrisdennis commented 8 years ago

The atomic reference used to return the previous mapping by side affect from the functions used in EhcacheWithLoaderWriter methods are incorrectly memoized. This means the statistics reported for a call will be correct for the first function invocation, and not for the final 'correct' invocation in the case the store invokes the method multiple times. This same bug is present for put, remove and replace.

chrisdennis commented 1 year ago

This might be fixed by Louis' long ago written "closable" event listener logic. Someone should revisit this code and make that assessment.

jitendra-nalwaya commented 1 year ago

Hi @chrisdennis ,

Observations when configure heap+offheap with CacheLoaderWriter:

Note: EhcacheWithLoaderWriter is removed by PR https://github.com/ehcache/ehcache3/pull/2501 in Oct 2018

1) Additions to statistics count depend on observer. a) The count increased when the observer's end() method was called. b) When OversizeMappingException throws in this scenario, the count is not increased.

2) The compute function is applied multiple times when an OversizeMappingException occurs during the put operation.

try {
  computeResult = backingMap().compute(key, computeFunction, fault);  // [1]
} catch (OversizeMappingException ex) {
  try {
    evictionAdvisor().setSwitchedOn(false);
    invokeValve();
    computeResult = backingMap().compute(key, computeFunction, fault); // [2]
  } catch (OversizeMappingException e) {
    throw new StoreAccessException("The element with key '" + key + "' is too large to be stored"
                                   + " in this offheap store.", e);
  } catch (RuntimeException e) {
    throw handleException(e);
  } finally {
    evictionAdvisor().setSwitchedOn(true);
  }
} catch (RuntimeException re) {
  throw handleException(re);
}

. a) OversizeMappingException triggered from org.terracotta.offheapstore.AbstractOffHeapClockCache (Offheap-store-2.5.3.jar). b) at [1] : Compute function is applied three times due to Offheap-store code flow. c) at [2] : Compute function is applied one time due to handleOversizeMappingException(key.hashCode()) method.