Git-репозиторий, содержащий проблему, можно найти здесь https://github.com/mdedetrich/scalacache-example
Проблема, с которой я сталкиваюсь в настоящее время, заключается в том, что я пытаюсь настроить независимый бэкэнд моего ScalaCache, настраивая его во время выполнения, используя typesafe config.
Проблема, с которой я столкнулся, заключается в том, что ScalaCache параметризует конструкторы кэша, т.е. для создания кэша кофеина вы должны сделать
ScalaCache(CaffeineCache())
, где, как для SentinelRedisCache
вы бы сделали
ScalaCache(SentinelRedisCache("", Set.empty, ""))
В моем случае я создал универсальную оболочку кэша с именем MyCache
, как показано ниже
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)
}
Нам нужно нестивместе с CacheRepr
, потому что именно так ScalaCache знает, как сериализовать любой тип T
.CaffeineCache
использует CacheRepr
, что составляет InMemoryRepr
, где SentinelRedisCache
использует CacheRepr
, что составляет Array[Byte]
.
И вот где суть проблемы, у меня есть Config
, который просто хранит, какой кэш используется, то есть
import scalacache.Cache
import scalacache.caffeine.CaffeineCache
import scalacache.redis.SentinelRedisCache
final case class ApplicationConfig(cache: Cache[_])
Причина, по которой он Cache[_]
, заключается в том, что во время компиляции мы не знаем, какой кеш используется, ApplicationConfig
будетсоздается во время выполнения с помощью либо CaffeineCache
/ SentinelRedisCache
.
И в этом суть проблемы, Scala не может найти неявное Codec
для подстановочного типа, если мы просто используем applicationConfig.cache
как конструктор, т.е. https://github.com/mdedetrich/scalacache-example/blob/master/src/main/scala/Main.scala#L17
Если мы раскомментируем вышеприведенную строку, мы получим
[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
Кто-нибудь знает, как решить эту проблему, по сути, я хочу указать это в моемApplicationConfig
, кеш имеет тип Cache[InMemoryRepr | Array[Byte]]
, а не просто Cache[_]
(так что компилятор Scala знает, что искать значения InMemoryRepr or Array[Byte]
и для MyCache
можно определить примерно так
final case class MyCache[CacheRepr <: InMemoryRepr | Array[Byte]](scalaCache: ScalaCache[CacheRepr])