CacheApi并不介意timeToIdle的EhCache配置

时间:2016-10-21 10:17:06

标签: java playframework ehcache playframework-2.5

我在播放框架2.5.6中设置缓存并使用timeToIdle属性进行讨论。

我的配置遵循官方documentation

中提供的配置

CONF / ehcache.xml中:

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="false"
         monitoring="autodetect" dynamicConfig="true">
    <diskStore path="java.io.tmpdir" />
    <cache name="userSession"
           maxEntriesLocalHeap="100000"
           maxEntriesLocalDisk="10000"
           eternal="false"
           diskSpoolBufferSizeMB="30"
           memoryStoreEvictionPolicy="LRU"

           timeToIdleSeconds="3"

           transactionalMode="off">
        <persistence strategy="localTempSwap" />
    </cache>
</ehcache>

CONF / application.conf:

play.cache {
    bindCaches = ["userSession"]
    createBoundCaches = false
}

在代码中,我通过@Inject @NamedCache("userSession")注入来获取缓存。

缓存被注入并且可以使用,但是根据我的观察,不使用timeToIdleInSeconds。

我的配置肯定已经解决,因为在日志中我可以找到:

2016-10-21 11:46:46,086 DEBUG n.s.e.config.ConfigurationFactory  ForkJoinPool-1-worker-1  [] - Configuring ehcache from URL: file:/src/LR/lr-facade/target/scala-2.11/classes/ehcache.xml

我尝试调试代码,发现在EhCache的播放实现中有:

play-cache_2.11-2.5.6-sources.jar!/play/api/cache/Cache.scala

  def set(key: String, value: Any, expiration: Duration) = {
    val element = new Element(key, value)
    expiration match {
      case infinite: Duration.Infinite => element.setEternal(true)
      case finite: FiniteDuration =>
        val seconds = finite.toSeconds
        if (seconds <= 0) {
          element.setTimeToLive(1)
        } else if (seconds > Int.MaxValue) {
          element.setTimeToLive(Int.MaxValue)
        } else {
          element.setTimeToLive(seconds.toInt)
        }
    }
    cache.put(element)
  }

如您所见,如果我没有提供ttl eternal设置为true。根据我在EhCache docs中所读到的,如果设定了永恒,对于整个缓存,ttl和tti不再重要。从代码中我看到,如果为Element设置了永久,ttittl设置为0

ehcache-core-2.6.11-sources.jar!/net/sf/ehcache/Element.java

public void setEternal(final boolean eternal) {
    if (eternal) {
        this.cacheDefaultLifespan = false;
        this.timeToIdle = 0;
        this.timeToLive = 0;
    } else if (isEternal()) {
        this.cacheDefaultLifespan = false;
        this.timeToIdle = Integer.MIN_VALUE;
        this.timeToLive = Integer.MIN_VALUE;
    }
}

有人有同样的问题吗?有人找到了它的解决方案吗?

当然我知道我可以通过在缓存中设置时间戳并检查它是否应该由myslef到期来解决它。

[更新]

忘记我在测试conf时发生了变化,并从中删除了一段永恒的财产。但是在我证明无论是否设置之后我所做的所有测试中,永恒属性总是正确的(因为它来自playCache代码)。

1 个答案:

答案 0 :(得分:0)

我只能使用Cache确认这是Play中Ehcache抽象的行为。

除非在将条目放入Duration时明确定义过期Cache,否则在映射级别将映射配置为永恒。这意味着任何Cache级别的到期配置都会被有效忽略,因为映射将始终指定每个映射设置。

另请注意,Play仅支持生存时间 / TTL ,而非空闲时间 / TTI 我认为这是件好事,因为 TTI 真的更接近容量控制而不是新鲜度。