-
-
Save miguel-vila/cf006d103e0c279553bc7550477f4599 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.disneystreaming.subscription.v2.infra.clients.pes | |
import cats.data.NonEmptyList | |
import com.disneystreaming.subscription.v2.core.errors.{ | |
ProductDetailsError, | |
ProductRetrievalFailed | |
} | |
import com.disneystreaming.subscription.v2.infra.clients.PriceEngineServiceClient | |
import com.disneystreaming.subscription.v2.infra.clients.model.pes.OrderItem | |
import scalacache.Cache | |
import scalacache.caffeine.CaffeineCache | |
import scalacache.memoization.memoizeF | |
import zio.ZIO | |
import scala.concurrent.duration._ | |
import scala.util.control.NonFatal | |
final case class CachedPriceEngineServiceClient[R]( | |
underlying: PriceEngineServiceClient[R], | |
defaultTtl: FiniteDuration | |
) extends PriceEngineServiceClient[R] { | |
private implicit val orderItemCache: Cache[NonEmptyList[OrderItem]] = | |
CaffeineCache[NonEmptyList[OrderItem]] | |
case class WrappedProductDetailsException private (error: ProductDetailsError) | |
extends Exception | |
import com.disneystreaming.subscription.v2.commons.utils.ZioEffect.modes._ | |
override def getOrderItems( | |
skus: NonEmptyList[String], | |
campaignCode: String, | |
voucherCode: String, | |
transactionCount: Long | |
): ZIO[ | |
R, | |
ProductDetailsError, | |
NonEmptyList[ | |
OrderItem | |
] | |
] = { | |
for { | |
resources <- ZIO.environment[R] | |
result <- memoizeF(Some(defaultTtl)) { | |
underlying | |
.getOrderItems( | |
skus, | |
campaignCode, | |
voucherCode, | |
transactionCount | |
) // Scaffeine's mode for ZIO works with throwable, so wrapped around throwable | |
.mapError(err => WrappedProductDetailsException(err): Throwable) | |
.provide(resources) | |
}.mapError { | |
case wrappedException: WrappedProductDetailsException => | |
wrappedException.error | |
case NonFatal(other) => ProductRetrievalFailed(other) | |
} | |
} yield result | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.disneystreaming.subscription.v2.infra.clients.pes | |
import cats.data.NonEmptyList | |
import com.disneystreaming.subscription.v2.core.errors.{ | |
ProductDetailsError, | |
ProductRetrievalFailed | |
} | |
import com.disneystreaming.subscription.v2.infra.clients.PriceEngineServiceClient | |
import com.disneystreaming.subscription.v2.infra.clients.model.pes.OrderItem | |
import scalacache.caffeine.CaffeineCache | |
import scalacache.memoization.{ | |
MemoizationConfig, | |
MethodCallToStringConverter, | |
cacheKeyExclude, | |
memoizeF | |
} | |
import scalacache.{Cache, CacheConfig} | |
import zio.{Task, ZIO} | |
import scala.concurrent.duration._ | |
import scala.util.control.NonFatal | |
final case class CachedPriceEngineServiceClient[R]( | |
underlying: PriceEngineServiceClient[R], | |
defaultTtl: FiniteDuration | |
) extends PriceEngineServiceClient[R] { | |
implicit val cacheConfig = CacheConfig( | |
memoization = MemoizationConfig(new MethodCallToStringConverter { | |
override def toString(fullClassName: String, | |
constructorParamss: IndexedSeq[IndexedSeq[Any]], | |
methodName: String, | |
paramss: IndexedSeq[IndexedSeq[Any]]): String = { | |
val key = MethodCallToStringConverter.excludeClassConstructorParams | |
.toString(fullClassName, constructorParamss, methodName, paramss) | |
println(s"PARAMS = ${paramss}") | |
println(s"constructorParamss = ${constructorParamss}") | |
println(s"KEY =$key") | |
key | |
} | |
}) | |
) | |
private implicit val orderItemCache: Cache[NonEmptyList[OrderItem]] = | |
CaffeineCache[NonEmptyList[OrderItem]] | |
case class WrappedProductDetailsException private (error: ProductDetailsError) | |
extends Exception | |
import com.disneystreaming.subscription.v2.commons.utils.ZioEffect.modes._ | |
override def getOrderItems( | |
skus: NonEmptyList[String], | |
campaignCode: String, | |
voucherCode: String, | |
transactionCount: Long | |
): ZIO[ | |
R, | |
ProductDetailsError, | |
NonEmptyList[ | |
OrderItem | |
] | |
] = { | |
for { | |
resources <- ZIO.environment[R] | |
result <- cache(skus, | |
campaignCode, | |
voucherCode, | |
transactionCount, | |
resources).mapError { | |
case wrappedException: WrappedProductDetailsException => | |
wrappedException.error | |
case NonFatal(other) => ProductRetrievalFailed(other) | |
} | |
} yield result | |
} | |
def cache( | |
skus: NonEmptyList[String], | |
campaignCode: String, | |
voucherCode: String, | |
transactionCount: Long, | |
@cacheKeyExclude resources: R | |
): Task[NonEmptyList[OrderItem]] = { | |
memoizeF(Some(defaultTtl)) { | |
underlying | |
.getOrderItems( | |
skus, | |
campaignCode, | |
voucherCode, | |
transactionCount | |
) | |
.mapError(err => WrappedProductDetailsException(err): Throwable) | |
.provide(resources) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment