diff --git a/cache/play-caffeine-cache/src/main/scala/play/api/cache/caffeine/CaffeineCacheApi.scala b/cache/play-caffeine-cache/src/main/scala/play/api/cache/caffeine/CaffeineCacheApi.scala index 90a18f9c5ca..7ab3e13ab88 100644 --- a/cache/play-caffeine-cache/src/main/scala/play/api/cache/caffeine/CaffeineCacheApi.scala +++ b/cache/play-caffeine-cache/src/main/scala/play/api/cache/caffeine/CaffeineCacheApi.scala @@ -28,6 +28,7 @@ import play.cache.{ SyncCacheApi => JavaSyncCacheApi } import scala.jdk.FutureConverters._ import scala.concurrent.duration.Duration +import scala.concurrent.duration._ import scala.concurrent.ExecutionContext import scala.concurrent.Future import scala.reflect.ClassTag @@ -183,7 +184,10 @@ class SyncCaffeineCacheApi @Inject() (val cache: NamedCaffeineCache[Any, Any]) e private val syncCache: Cache[Any, Any] = cache.synchronous() override def set(key: String, value: Any, expiration: Duration): Unit = { - syncCache.put(key, ExpirableCacheValue(value, Some(expiration))) + if (!expiration.isFinite || !expiration.lteq(0.seconds)) { + // Cache only if expiration is greater than 0 (0 and below won't cache) + syncCache.put(key, ExpirableCacheValue(value, Some(expiration))) + } Done } diff --git a/cache/play-caffeine-cache/src/main/scala/play/api/cache/caffeine/DefaultCaffeineExpiry.scala b/cache/play-caffeine-cache/src/main/scala/play/api/cache/caffeine/DefaultCaffeineExpiry.scala index 6bd816c3a18..3b92d2b7e53 100644 --- a/cache/play-caffeine-cache/src/main/scala/play/api/cache/caffeine/DefaultCaffeineExpiry.scala +++ b/cache/play-caffeine-cache/src/main/scala/play/api/cache/caffeine/DefaultCaffeineExpiry.scala @@ -31,9 +31,10 @@ private[caffeine] class DefaultCaffeineExpiry extends Expiry[String, ExpirableCa private def calculateExpirationTime(durationMaybe: Option[Duration]): Long = { durationMaybe match { - case Some(duration) if duration.isFinite && duration.lteq(0.second) => 1.second.toNanos - case Some(duration) if duration.isFinite => duration.toNanos - case _ => Long.MaxValue + case Some(duration) if duration.isFinite && duration.lteq(0.second) => + 0.seconds.toNanos // Will always end up in a cache miss, so this equals to not caching at all: https://github.com/ben-manes/caffeine/discussions/803 + case Some(duration) if duration.isFinite => duration.toNanos + case _ => Long.MaxValue } } } diff --git a/cache/play-ehcache/src/main/scala/play/api/cache/ehcache/EhCacheApi.scala b/cache/play-ehcache/src/main/scala/play/api/cache/ehcache/EhCacheApi.scala index d8333cc2eab..bfd8be7ed05 100644 --- a/cache/play-ehcache/src/main/scala/play/api/cache/ehcache/EhCacheApi.scala +++ b/cache/play-ehcache/src/main/scala/play/api/cache/ehcache/EhCacheApi.scala @@ -188,19 +188,24 @@ private[play] case class EhCacheExistsException(msg: String, cause: Throwable) e class SyncEhCacheApi @Inject() (private[ehcache] val cache: Ehcache) extends SyncCacheApi { override def set(key: String, value: Any, expiration: Duration): Unit = { val element = new Element(key, value) + var doCache = true expiration match { case infinite: Duration.Infinite => element.setEternal(true) case finite: FiniteDuration => val seconds = finite.toSeconds if (seconds <= 0) { - element.setTimeToLive(1) + // We don't even put the element in the cache, why should we? + // Obviously someone wants to put something in the cache for 0 (or less) seconds... + doCache = false } else if (seconds > Int.MaxValue) { element.setTimeToLive(Int.MaxValue) } else { element.setTimeToLive(seconds.toInt) } } - cache.put(element) + if (doCache) { + cache.put(element) + } Done }