class TimelineMetricCache extends UpdatingSelfPopulatingCache {

  public TimelineMetrics getAppTimelineMetricsFromCache(TimelineAppMetricCacheKey key) throws IllegalArgumentException, IOException {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Fetching metrics with key: {}", key);
    }

    // Make sure key is valid
    validateKey(key);

    Element element = null;
    try {
      element = get(key);
    } catch (LockTimeoutException le) {
      // Ehcache masks the Socket Timeout to look as a LockTimeout
      Throwable t = le.getCause();
      if (t instanceof CacheException) {
        t = t.getCause();
        if (t instanceof SocketTimeoutException) {
          throw new SocketTimeoutException(t.getMessage());
        }
        if (t instanceof ConnectException) {
          throw new ConnectException(t.getMessage());
        }
      }
    }

    TimelineMetrics timelineMetrics = new TimelineMetrics();
    if (element != null && element.getObjectValue() != null) {
      TimelineMetricsCacheValue value = (TimelineMetricsCacheValue) element.getObjectValue();
      if (LOG.isDebugEnabled()) {
        LOG.debug("Returning value from cache: {}", value);
      }
      timelineMetrics = value.getTimelineMetrics();
    }

    if (LOG.isDebugEnabled()) {
      // Print stats every 100 calls - Note: Supported in debug mode only
      if (printCacheStatsCounter.getAndIncrement() == 0) {
        StatisticsGateway statistics = this.getStatistics();
        LOG.debug("Metrics cache stats => \n, Evictions = {}, Expired = {}, Hits = {}, Misses = {}, Hit ratio = {}, Puts = {}, Size in MB = {}",
          statistics.cacheEvictedCount(), statistics.cacheExpiredCount(), statistics.cacheHitCount(), statistics.cacheMissCount(), statistics.cacheHitRatio(),
          statistics.cachePutCount(), statistics.getLocalHeapSizeInBytes() / 1048576);
      } else {
        printCacheStatsCounter.compareAndSet(100, 0);
      }
    }

    return timelineMetrics;
  }

  public  TimelineMetricCache(Ehcache cache, UpdatingCacheEntryFactory factory);

}