Skip to content

Commit 7fc0778

Browse files
committed
BREAKING CHANGE: use simple cache instead of scala-cache
1 parent 76d6ce9 commit 7fc0778

File tree

16 files changed

+187
-448
lines changed

16 files changed

+187
-448
lines changed

build.sbt

+21-27
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,21 @@
11
import CompileFlags._
2-
import sbt.Keys.crossScalaVersions
32
import DependenciesScopesHandler._
43
import Dependencies._
54
import PublishSettings.localCacheSettings
65
import org.typelevel.scalacoptions.ScalacOptions
76

8-
lazy val scala212 = "2.12.13"
9-
lazy val scala213 = "2.13.11"
10-
lazy val supportedScalaVersions = List(scala213, scala212)
7+
lazy val scala213 = "2.13.11"
118

129
Global / onChangedBuildSource := ReloadOnSourceChanges
1310

1411
inThisBuild {
1512
List(
16-
organization := "com.colisweb",
17-
scalaVersion := scala213,
18-
crossScalaVersions := supportedScalaVersions,
19-
scalafmtOnCompile := true,
20-
scalafmtCheck := true,
21-
scalafmtSbtCheck := true,
22-
Test / fork := true,
13+
organization := "com.colisweb",
14+
scalaVersion := scala213,
15+
scalafmtOnCompile := true,
16+
scalafmtCheck := true,
17+
scalafmtSbtCheck := true,
18+
Test / fork := true,
2319
scalacOptions ++= crossScalacOptions(scalaVersion.value),
2420
localCacheSettings
2521
)
@@ -29,20 +25,20 @@ inThisBuild {
2925
lazy val root = Project(id = "scala-distances", base = file("."))
3026
.settings(moduleName := "root")
3127
.settings(noPublishSettings)
32-
.aggregate(core, `google-provider`, `here-provider`, `redis-cache`, `caffeine-cache`, tests)
33-
.dependsOn(core, `google-provider`, `here-provider`, `redis-cache`, `caffeine-cache`, tests)
28+
.aggregate(core, `google-provider`, `here-provider`, tests)
29+
.dependsOn(core, `google-provider`, `here-provider`, tests)
3430

3531
lazy val core = project
3632
.settings(moduleName := "scala-distances-core")
3733
.settings(Test / tpolecatExcludeOptions += ScalacOptions.warnNonUnitStatement)
38-
.settings(libraryDependencies ++= compileDependencies(cats, scalaCache, squants))
34+
.settings(libraryDependencies ++= compileDependencies(squants, simplecacheWrapperCats))
3935
.settings(
4036
libraryDependencies ++= testDependencies(
41-
monix,
4237
mockitoScalaScalatest,
4338
scalacheck,
4439
scalatest,
45-
scalatestPlus
40+
scalatestPlus,
41+
simplecacheMemory
4642
)
4743
)
4844

@@ -52,7 +48,7 @@ lazy val `google-provider` = project
5248
.in(file("providers/google"))
5349
.settings(moduleName := "scala-distances-provider-google")
5450
.settings(
55-
libraryDependencies ++= compileDependencies(catsEffect, enumeratum, googleMaps, loggingInterceptor, refined)
51+
libraryDependencies ++= compileDependencies(enumeratum, googleMaps, loggingInterceptor, refined)
5652
)
5753
.dependsOn(core)
5854

@@ -61,15 +57,13 @@ lazy val `here-provider` = project
6157
.settings(moduleName := "scala-distances-provider-here")
6258
.settings(
6359
libraryDependencies ++= compileDependencies(
64-
catsEffect,
6560
circe,
6661
circeGeneric,
6762
circeGenericExtras,
6863
circeJawn,
6964
logstashLogbackEncode,
7065
refined,
71-
requests,
72-
scalaCompat
66+
requests
7367
)
7468
)
7569
.dependsOn(core)
@@ -79,22 +73,22 @@ lazy val `here-provider` = project
7973
lazy val `redis-cache` = project
8074
.in(file("caches/redis"))
8175
.settings(moduleName := "scala-distances-cache-redis")
82-
.settings(libraryDependencies ++= compileDependencies(scalaCacheRedis))
76+
.settings(libraryDependencies ++= compileDependencies(simplecacheRedisCirce))
8377
.dependsOn(core)
8478

85-
lazy val `caffeine-cache` = project
86-
.in(file("caches/caffeine"))
87-
.settings(moduleName := "scala-distances-cache-caffeine")
88-
.settings(libraryDependencies ++= compileDependencies(scalaCacheCaffeine))
79+
lazy val `memory-guava` = project
80+
.in(file("caches/memory-guava"))
81+
.settings(moduleName := "scala-distances-memory-guava")
82+
.settings(libraryDependencies ++= compileDependencies(simplecacheMemoryGuava))
8983
.dependsOn(core)
9084

9185
//// Meta projects
9286

9387
lazy val tests = project
9488
.settings(noPublishSettings)
9589
.settings(Test / tpolecatExcludeOptions += ScalacOptions.warnNonUnitStatement)
96-
.dependsOn(core % "test->test;compile->compile", `google-provider`, `here-provider`, `redis-cache`, `caffeine-cache`)
97-
.settings(libraryDependencies ++= testDependencies(pureconfig, refinedPureconfig, scalaCacheCatsEffect, approvals))
90+
.dependsOn(core % "test->test;compile->compile", `google-provider`, `here-provider`, `redis-cache`, `memory-guava`)
91+
.settings(libraryDependencies ++= testDependencies(pureconfig, refinedPureconfig, simplecacheRedisCirce, approvals))
9892

9993
/** Copied from Cats */
10094
lazy val noPublishSettings = Seq(

caches/caffeine/src/main/scala/com/colisweb/distances/caches/CaffeineCache.scala

-16
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.colisweb.distances.caches
2+
3+
import cats.effect.Sync
4+
import com.colisweb.simplecache.memory.guava.GuavaCache
5+
import com.colisweb.simplecache.wrapper.cats.CatsCache
6+
7+
import scala.concurrent.duration.FiniteDuration
8+
9+
object CatsGuavaCache {
10+
11+
def apply[F[_]: Sync, K, V](ttl: Option[FiniteDuration]): CatsCache[F, K, V] =
12+
CatsCache(new GuavaCache[K, V](ttl))
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.colisweb.distances.caches
2+
3+
import cats.effect.Sync
4+
import com.colisweb.simplecache.redis.RedisConfiguration
5+
import com.colisweb.simplecache.redis.RedisConfiguration.pool
6+
import com.colisweb.simplecache.redis.codec._
7+
import com.colisweb.simplecache.redis.circe.RedisCirceCache
8+
import com.colisweb.simplecache.wrapper.cats.CatsCache
9+
10+
import scala.concurrent.duration.FiniteDuration
11+
12+
object CatsRedisCache {
13+
14+
def apply[F[_]: Sync, K, V](
15+
configuration: RedisConfiguration,
16+
ttl: Option[FiniteDuration],
17+
keyEncoder: Encoder[K] = AnyEncoder()
18+
)(implicit codec: io.circe.Codec[V]): CatsCache[F, K, V] =
19+
CatsCache(new RedisCirceCache[K, V](pool(configuration), ttl)(keyEncoder, codec))
20+
}

caches/redis/src/main/scala/com/colisweb/distances/caches/RedisCache.scala

-20
This file was deleted.

caches/redis/src/main/scala/com/colisweb/distances/caches/RedisConfiguration.scala

-19
This file was deleted.

core/src/main/scala/com/colisweb/distances/Distances.scala

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package com.colisweb.distances
22

3+
import cats.effect.Sync
34
import cats.{Applicative, MonadError}
45
import com.colisweb.distances.bird.HaversineDistanceApi
5-
import com.colisweb.distances.cache.{Cache, DistanceFromCache, DistanceWithCache}
6+
import com.colisweb.distances.cache.{DistanceFromCache, DistanceWithCache}
67
import com.colisweb.distances.correction.CorrectPastDepartureTime
78
import com.colisweb.distances.model._
9+
import com.colisweb.simplecache.wrapper.cats.CatsCache
810

911
import java.time.Clock
1012
import scala.concurrent.duration.FiniteDuration
@@ -27,7 +29,7 @@ case class Distances[F[_], P](api: DistanceApi[F, P]) {
2729
)(when: PartialFunction[Throwable, F[Unit]])(implicit F: MonadError[F, Throwable]): Distances[F, P] =
2830
copy(api = Fallback(api, other.api, when))
2931

30-
def caching(cache: Cache[F, P, PathResult])(implicit F: MonadError[F, Throwable]): Distances[F, P] =
32+
def caching(cache: CatsCache[F, P, PathResult])(implicit F: Sync[F]): Distances[F, P] =
3133
copy(api = DistanceWithCache(cache, api))
3234

3335
def correctPastDepartureTime(
@@ -44,7 +46,7 @@ object Distances {
4446

4547
implicit def from[F[_], P](api: DistanceApi[F, P]): Distances[F, P] = Distances(api)
4648

47-
implicit def fromCache[F[_], P](cache: Cache[F, P, PathResult])(implicit
49+
implicit def fromCache[F[_], P](cache: CatsCache[F, P, PathResult])(implicit
4850
F: MonadError[F, Throwable]
4951
): Distances[F, P] =
5052
from(DistanceFromCache(cache))

core/src/main/scala/com/colisweb/distances/cache/Cache.scala

-7
This file was deleted.

core/src/main/scala/com/colisweb/distances/cache/CacheKey.scala

-18
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
package com.colisweb.distances.cache
22

33
import cats.MonadError
4+
import cats.effect.Sync
45
import cats.implicits._
56
import com.colisweb.distances.DistanceApi
67
import com.colisweb.distances.model.PathResult
7-
import org.slf4j.{Logger, LoggerFactory}
8+
import com.colisweb.simplecache.wrapper.cats._
89

910
import scala.util.control.NoStackTrace
1011

1112
case class DistanceFromCache[F[_], P](
12-
cache: Cache[F, P, PathResult]
13+
cache: CatsCache[F, P, PathResult]
1314
)(implicit F: MonadError[F, Throwable])
1415
extends DistanceApi[F, P] {
1516

@@ -22,29 +23,10 @@ case class DistanceFromCache[F[_], P](
2223

2324
final case class CacheMissError(key: Any) extends RuntimeException(s"No entry in cache for $key") with NoStackTrace
2425

25-
case class DistanceWithCache[F[_], P](
26-
cache: Cache[F, P, PathResult],
26+
case class DistanceWithCache[F[_]: Sync, P](
27+
cache: CatsCache[F, P, PathResult],
2728
api: DistanceApi[F, P]
28-
)(implicit F: MonadError[F, Throwable])
29-
extends DistanceApi[F, P] {
30-
private lazy val logger: Logger = LoggerFactory.getLogger(getClass)
31-
override def distance(path: P): F[PathResult] = {
32-
cache.get(path).attempt.flatMap {
33-
case Right(Some(distance)) => F.pure(distance)
34-
case Right(None) => computeAndCacheDistance(path)
35-
case Left(error) =>
36-
F.pure(logger.warn(s"Fail to get distance from cache for $path", error)) *>
37-
computeAndCacheDistance(path)
38-
}
39-
}
29+
) extends DistanceApi[F, P] {
30+
override def distance(path: P): F[PathResult] = cache.getOrElseUpdate(path, api.distance(path))
4031

41-
private def computeAndCacheDistance(path: P): F[PathResult] = {
42-
api
43-
.distance(path)
44-
.flatTap(
45-
cache
46-
.put(path, _)
47-
.handleError(logger.warn(s"Fail to get distance from cache for $path", _))
48-
)
49-
}
5032
}

core/src/main/scala/com/colisweb/distances/cache/ScalaCacheCache.scala

-29
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,36 @@
11
package com.colisweb.distances.cache
22

3+
import cats.effect.IO
34
import com.colisweb.distances.Distances
45
import com.colisweb.distances.model.path.DirectedPath
56
import com.colisweb.distances.model.{PathResult, Point}
67
import com.colisweb.distances.util.FromMapDistances
8+
import com.colisweb.simplecache.memory.MemoryCache
9+
import com.colisweb.simplecache.wrapper.cats.CatsCache
710
import org.scalatest.matchers.should.Matchers
811
import org.scalatest.wordspec.AnyWordSpec
912

10-
import scala.util.{Failure, Try}
11-
1213
class CacheSpec extends AnyWordSpec with Matchers {
1314

14-
private val failingCache: Cache[Try, DirectedPath, PathResult] =
15-
new Cache[Try, DirectedPath, PathResult] {
16-
private val failure: Failure[Nothing] = Failure(new RuntimeException("failure"))
17-
override def get(key: DirectedPath): Try[Option[PathResult]] = failure
18-
override def put(key: DirectedPath, value: PathResult): Try[Any] = failure
15+
private val failingCache: CatsCache[IO, DirectedPath, PathResult] = {
16+
new CatsCache[IO, DirectedPath, PathResult](new MemoryCache()) {
17+
private val failure: IO[Nothing] = IO.raiseError(new RuntimeException("failure"))
18+
override def get(key: DirectedPath): IO[Option[PathResult]] = failure
19+
override def update(key: DirectedPath, value: PathResult): IO[Unit] = failure
1920
}
21+
}
2022

2123
private val path: DirectedPath = DirectedPath(Point(0, 0), Point(0, 0))
2224
private val pathResult: PathResult = PathResult(1, 1)
2325

24-
private val distanceMap: Distances[Try, DirectedPath] =
25-
FromMapDistances[Try]
26+
private val distanceMap: Distances[IO, DirectedPath] =
27+
FromMapDistances[IO]
2628
.fromMap(Map(path -> pathResult))
2729
.caching(failingCache)
2830

2931
"Failing cache" should {
3032
"not propagate failure on caching" in {
31-
distanceMap.api.distance(path).get shouldBe pathResult
33+
distanceMap.api.distance(path).unsafeRunSync() shouldBe pathResult
3234
}
3335
}
3436
}

0 commit comments

Comments
 (0)