Skip to content

Commit

Permalink
It's better if it's traverse! (no, really)
Browse files Browse the repository at this point in the history
By traversing on the entry's TTL we get the opportunity to avoid
calculating the time in case there's no TTL. That might give us some
extra performance in case of infinitely long-lived keys.

The constraint is more powerful, but all the caching implementations
will be at least monads, so it's fine. And Clock is only possible to
implement in a real scenario for instances of Sync.
  • Loading branch information
kubukoz committed Feb 7, 2020
1 parent 1b33e95 commit 4c52ee5
Showing 1 changed file with 8 additions and 4 deletions.
12 changes: 8 additions & 4 deletions modules/core/shared/src/main/scala/scalacache/Entry.scala
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package scalacache

import java.time.{Instant}
import java.time.Instant
import cats.effect.Clock
import java.util.concurrent.TimeUnit
import cats.implicits._
import language.higherKinds
import cats.Functor
import cats.Applicative

/**
* A cache entry with an optional expiry time
Expand All @@ -15,6 +15,10 @@ case class Entry[F[_], +A](value: A, expiresAt: Option[Instant]) {
/**
* Has the entry expired yet?
*/
def isExpired(implicit clock: Clock[F], functor: Functor[F]): F[Boolean] =
clock.monotonic(TimeUnit.MILLISECONDS).map(Instant.ofEpochMilli(_)).map(now => expiresAt.exists(_.isBefore(now)))
def isExpired(implicit clock: Clock[F], applicative: Applicative[F]): F[Boolean] =
expiresAt
.traverse { ttl =>
clock.monotonic(TimeUnit.MILLISECONDS).map(Instant.ofEpochMilli(_)).map(ttl.isBefore(_))
}
.map(_.contains(true))
}

0 comments on commit 4c52ee5

Please sign in to comment.