The git repo that contains the issue can be found here https://github.com/mdedetrich/scalacache-example
The problem that I currently have is that I am trying to make my ScalaCache backend agnostic with it being configurable at runtime using typesafe config.
The issue I have is that ScalaCache parameterizes the constructors of the cache, i.e. to construct a Caffeine cache you would do
ScalaCache(CaffeineCache())
where as for a SentinelRedisCache
you would do
ScalaCache(SentinelRedisCache("", Set.empty, ""))
In my case, I have created a generic cache wrapper called MyCache
as shown below
import scalacache.ScalaCache
import scalacache.serialization.Codec
final case class MyCache[CacheRepr](scalaCache: ScalaCache[CacheRepr])(
implicit stringCodec: Codec[Int, CacheRepr]) {
def putInt(value: Int) = scalaCache.cache.put[Int]("my_int", value, None)
}
We need to carry the CacheRepr
along because this is how ScalaCache knows how to serialize any type T
. CaffeineCache
uses a CacheRepr
which is InMemoryRepr
where as SentinelRedisCache
uses a CacheRepr
which is Array[Byte]
.
And this is where the crux of the problem is, I have an Config
which just stores which cache is being used, i.e.
import scalacache.Cache
import scalacache.caffeine.CaffeineCache
import scalacache.redis.SentinelRedisCache
final case class ApplicationConfig(cache: Cache[_])
The reason why its a Cache[_]
is because at compile time we don't know what cache is being used, ApplicationConfig
will be instantiated at runtime with either CaffeineCache
/SentinelRedisCache
.
And this is where the crux of the problem is, Scala is unable to find an implicit Codec
for the wildcard type if we just us applicationConfig.cache
as a constructor, i.e. https://github.com/mdedetrich/scalacache-example/blob/master/src/main/scala/Main.scala#L17
If we uncomment the above line, we get
[error] /Users/mdedetrich/github/scalacache-example/src/main/scala/Main.scala:17:37: Could not find any Codecs for type Int and _$1. Please provide one or import scalacache._
[error] Error occurred in an application involving default arguments.
[error] val myCache3: MyCache[_] = MyCache(ScalaCache(applicationConfig.cache)) // This doesn't
Does anyone know how to solve this problem, essentially I want to specify that in my ApplicationConfig
, cache is of type Cache[InMemoryRepr | Array[Byte]]
rather than just Cache[_]
(so that the Scala compiler knows to look up implicits of either InMemoryRepr or Array[Byte]
and for MyCache
to be defined something like this
final case class MyCache[CacheRepr <: InMemoryRepr | Array[Byte]](scalaCache: ScalaCache[CacheRepr])