Skip to content

Commit

Permalink
stop using java clock in ScopedCache (#134)
Browse files Browse the repository at this point in the history
* stop using java clock in ScopedCache

* After Adam review

* after second adam's review
  • Loading branch information
strokyl authored Apr 5, 2023
1 parent ce023f3 commit 3a9c3e9
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 93 deletions.
27 changes: 10 additions & 17 deletions zio-cache/shared/src/main/scala/zio/cache/ScopedCache.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package zio.cache
import zio._
import zio.internal.MutableConcurrentQueue

import java.time.{Clock, Duration, Instant}
import java.time.{Duration, Instant}
import java.util
import java.util.concurrent.atomic.{AtomicBoolean, AtomicInteger, LongAdder}
import scala.jdk.CollectionConverters._
Expand Down Expand Up @@ -99,17 +99,9 @@ object ScopedCache {
def makeWith[Key, Environment, Error, Value](
capacity: Int,
scopedLookup: ScopedLookup[Key, Environment, Error, Value]
)(timeToLive: Exit[Error, Value] => Duration): URIO[Environment with Scope, ScopedCache[Key, Error, Value]] =
makeWith(capacity, scopedLookup, Clock.systemUTC())(timeToLive)

//util for test because it allow to inject a mocked Clock
private[cache] def makeWith[Key, Environment, Error, Value](
capacity: Int,
scopedLookup: ScopedLookup[Key, Environment, Error, Value],
clock: Clock
)(timeToLive: Exit[Error, Value] => Duration): URIO[Environment with Scope, ScopedCache[Key, Error, Value]] =
ZIO
.acquireRelease(buildWith(capacity, scopedLookup, clock)(timeToLive))(_.invalidateAll)
.acquireRelease(buildWith(capacity, scopedLookup)(timeToLive))(_.invalidateAll)
.tap { scopedCache =>
runFreeExpiredResourcesLoopInBackground(scopedCache)
}
Expand All @@ -123,16 +115,17 @@ object ScopedCache {

private def buildWith[Key, Environment, Error, Value](
capacity: Int,
scopedLookup: ScopedLookup[Key, Environment, Error, Value],
clock: Clock
scopedLookup: ScopedLookup[Key, Environment, Error, Value]
)(
timeToLive: Exit[Error, Value] => Duration
): URIO[Environment, ScopedCacheImplementation[Key, Environment, Error, Value]] =
ZIO
.environment[Environment]
.map { environment =>
new ScopedCacheImplementation(capacity, scopedLookup, clock, timeToLive, environment)
}
ZIO.clock.flatMap { clock =>
ZIO
.environment[Environment]
.map { environment =>
new ScopedCacheImplementation(capacity, scopedLookup, timeToLive, clock, environment)
}
}

/**
* A `MapValue` represents a value in the cache. A value may either be
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@ package zio.cache
import zio.cache.ScopedCache.Finalizer
import zio.cache.ScopedCacheImplementation.{CacheState, MapValue}
import zio.internal.MutableConcurrentQueue
import zio.{Exit, IO, Scope, UIO, ZEnvironment, ZIO}
import zio.{Clock, Exit, IO, Scope, UIO, Unsafe, ZEnvironment, ZIO}

import java.time.{Clock, Duration, Instant}
import java.time.{Duration, Instant}
import java.util
import java.util.concurrent.atomic.{AtomicBoolean, AtomicInteger, LongAdder}
import scala.jdk.CollectionConverters._

private[cache] class ScopedCacheImplementation[Key, Environment, Error, Value](
capacity: Int,
scopedLookup: ScopedLookup[Key, Environment, Error, Value],
clock: Clock,
timeToLive: Exit[Error, Value] => Duration,
clock: Clock,
environment: ZEnvironment[Environment]
) extends ScopedCache[Key, Error, Value] {
private val cacheState = CacheState.initial[Key, Error, Value]()
Expand Down Expand Up @@ -86,7 +86,7 @@ private[cache] class ScopedCacheImplementation[Key, Environment, Error, Value](
}
}

def freeExpired: UIO[Int] = ZIO.suspendSucceed {
def freeExpired: UIO[Int] = ZIO.suspendSucceedUnsafe { implicit unsafe =>
var expiredKey = List.empty[Key]
map.entrySet().forEach { entry =>
entry.getValue match {
Expand All @@ -106,7 +106,7 @@ private[cache] class ScopedCacheImplementation[Key, Environment, Error, Value](

override def get(k: Key): ZIO[Scope, Error, Value] =
lookupValueOf(k).memoize.flatMap { lookupValue =>
ZIO.suspendSucceed {
ZIO.suspendSucceedUnsafe { implicit unsafe =>
var key: MapKey[Key] = null
var value = map.get(k)
if (value eq null) {
Expand Down Expand Up @@ -155,7 +155,7 @@ private[cache] class ScopedCacheImplementation[Key, Environment, Error, Value](
case MapValue.Pending(_, scopedEffect) =>
scopedEffect
case completeResult @ MapValue.Complete(_, _, _, _, ttl) =>
if (hasExpired(ttl)) {
if (hasExpired(ttl)(Unsafe.unsafe)) {
ZIO.succeed(get(k))
} else {
if (map.replace(k, completeResult, MapValue.Refreshing(scoped, completeResult))) {
Expand Down Expand Up @@ -200,7 +200,7 @@ private[cache] class ScopedCacheImplementation[Key, Environment, Error, Value](
} yield (exit, scope.close(_)))
.onInterrupt(ZIO.succeed(map.remove(key)))
.flatMap { case (exit, release) =>
val now = Instant.now(clock)
val now = Unsafe.unsafe(clock.unsafe.instant()(_))
val expiredAt = now.plus(timeToLive(exit))
exit match {
case Exit.Success(value) =>
Expand Down Expand Up @@ -236,8 +236,8 @@ private[cache] class ScopedCacheImplementation[Key, Environment, Error, Value](
.memoize
} yield scopedEffect.flatten

private def hasExpired(timeToLive: Instant) =
Instant.now(clock).isAfter(timeToLive)
private def hasExpired(timeToLive: Instant)(implicit unsafe: Unsafe) =
clock.unsafe.instant().isAfter(timeToLive)
}

object ScopedCacheImplementation {
Expand Down
26 changes: 0 additions & 26 deletions zio-cache/shared/src/test/scala/zio/cache/MockedJavaClock.scala

This file was deleted.

Loading

0 comments on commit 3a9c3e9

Please sign in to comment.