Skip to content

Commit 3a9c3e9

Browse files
authored
stop using java clock in ScopedCache (#134)
* stop using java clock in ScopedCache * After Adam review * after second adam's review
1 parent ce023f3 commit 3a9c3e9

File tree

4 files changed

+40
-93
lines changed

4 files changed

+40
-93
lines changed

zio-cache/shared/src/main/scala/zio/cache/ScopedCache.scala

+10-17
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ package zio.cache
1919
import zio._
2020
import zio.internal.MutableConcurrentQueue
2121

22-
import java.time.{Clock, Duration, Instant}
22+
import java.time.{Duration, Instant}
2323
import java.util
2424
import java.util.concurrent.atomic.{AtomicBoolean, AtomicInteger, LongAdder}
2525
import scala.jdk.CollectionConverters._
@@ -99,17 +99,9 @@ object ScopedCache {
9999
def makeWith[Key, Environment, Error, Value](
100100
capacity: Int,
101101
scopedLookup: ScopedLookup[Key, Environment, Error, Value]
102-
)(timeToLive: Exit[Error, Value] => Duration): URIO[Environment with Scope, ScopedCache[Key, Error, Value]] =
103-
makeWith(capacity, scopedLookup, Clock.systemUTC())(timeToLive)
104-
105-
//util for test because it allow to inject a mocked Clock
106-
private[cache] def makeWith[Key, Environment, Error, Value](
107-
capacity: Int,
108-
scopedLookup: ScopedLookup[Key, Environment, Error, Value],
109-
clock: Clock
110102
)(timeToLive: Exit[Error, Value] => Duration): URIO[Environment with Scope, ScopedCache[Key, Error, Value]] =
111103
ZIO
112-
.acquireRelease(buildWith(capacity, scopedLookup, clock)(timeToLive))(_.invalidateAll)
104+
.acquireRelease(buildWith(capacity, scopedLookup)(timeToLive))(_.invalidateAll)
113105
.tap { scopedCache =>
114106
runFreeExpiredResourcesLoopInBackground(scopedCache)
115107
}
@@ -123,16 +115,17 @@ object ScopedCache {
123115

124116
private def buildWith[Key, Environment, Error, Value](
125117
capacity: Int,
126-
scopedLookup: ScopedLookup[Key, Environment, Error, Value],
127-
clock: Clock
118+
scopedLookup: ScopedLookup[Key, Environment, Error, Value]
128119
)(
129120
timeToLive: Exit[Error, Value] => Duration
130121
): URIO[Environment, ScopedCacheImplementation[Key, Environment, Error, Value]] =
131-
ZIO
132-
.environment[Environment]
133-
.map { environment =>
134-
new ScopedCacheImplementation(capacity, scopedLookup, clock, timeToLive, environment)
135-
}
122+
ZIO.clock.flatMap { clock =>
123+
ZIO
124+
.environment[Environment]
125+
.map { environment =>
126+
new ScopedCacheImplementation(capacity, scopedLookup, timeToLive, clock, environment)
127+
}
128+
}
136129

137130
/**
138131
* A `MapValue` represents a value in the cache. A value may either be

zio-cache/shared/src/main/scala/zio/cache/ScopedCacheImplementation.scala

+9-9
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@ package zio.cache
33
import zio.cache.ScopedCache.Finalizer
44
import zio.cache.ScopedCacheImplementation.{CacheState, MapValue}
55
import zio.internal.MutableConcurrentQueue
6-
import zio.{Exit, IO, Scope, UIO, ZEnvironment, ZIO}
6+
import zio.{Clock, Exit, IO, Scope, UIO, Unsafe, ZEnvironment, ZIO}
77

8-
import java.time.{Clock, Duration, Instant}
8+
import java.time.{Duration, Instant}
99
import java.util
1010
import java.util.concurrent.atomic.{AtomicBoolean, AtomicInteger, LongAdder}
1111
import scala.jdk.CollectionConverters._
1212

1313
private[cache] class ScopedCacheImplementation[Key, Environment, Error, Value](
1414
capacity: Int,
1515
scopedLookup: ScopedLookup[Key, Environment, Error, Value],
16-
clock: Clock,
1716
timeToLive: Exit[Error, Value] => Duration,
17+
clock: Clock,
1818
environment: ZEnvironment[Environment]
1919
) extends ScopedCache[Key, Error, Value] {
2020
private val cacheState = CacheState.initial[Key, Error, Value]()
@@ -86,7 +86,7 @@ private[cache] class ScopedCacheImplementation[Key, Environment, Error, Value](
8686
}
8787
}
8888

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

107107
override def get(k: Key): ZIO[Scope, Error, Value] =
108108
lookupValueOf(k).memoize.flatMap { lookupValue =>
109-
ZIO.suspendSucceed {
109+
ZIO.suspendSucceedUnsafe { implicit unsafe =>
110110
var key: MapKey[Key] = null
111111
var value = map.get(k)
112112
if (value eq null) {
@@ -155,7 +155,7 @@ private[cache] class ScopedCacheImplementation[Key, Environment, Error, Value](
155155
case MapValue.Pending(_, scopedEffect) =>
156156
scopedEffect
157157
case completeResult @ MapValue.Complete(_, _, _, _, ttl) =>
158-
if (hasExpired(ttl)) {
158+
if (hasExpired(ttl)(Unsafe.unsafe)) {
159159
ZIO.succeed(get(k))
160160
} else {
161161
if (map.replace(k, completeResult, MapValue.Refreshing(scoped, completeResult))) {
@@ -200,7 +200,7 @@ private[cache] class ScopedCacheImplementation[Key, Environment, Error, Value](
200200
} yield (exit, scope.close(_)))
201201
.onInterrupt(ZIO.succeed(map.remove(key)))
202202
.flatMap { case (exit, release) =>
203-
val now = Instant.now(clock)
203+
val now = Unsafe.unsafe(clock.unsafe.instant()(_))
204204
val expiredAt = now.plus(timeToLive(exit))
205205
exit match {
206206
case Exit.Success(value) =>
@@ -236,8 +236,8 @@ private[cache] class ScopedCacheImplementation[Key, Environment, Error, Value](
236236
.memoize
237237
} yield scopedEffect.flatten
238238

239-
private def hasExpired(timeToLive: Instant) =
240-
Instant.now(clock).isAfter(timeToLive)
239+
private def hasExpired(timeToLive: Instant)(implicit unsafe: Unsafe) =
240+
clock.unsafe.instant().isAfter(timeToLive)
241241
}
242242

243243
object ScopedCacheImplementation {

zio-cache/shared/src/test/scala/zio/cache/MockedJavaClock.scala

-26
This file was deleted.

0 commit comments

Comments
 (0)