cb372/scalacache

cachingF: conditionally cache based on function evaluation result type

Opened this issue · 1 comments

Hello,

I want use cache to store token evaluations for given client credentials:

def fetchToken(clientCredentials: ClientCredentials): Future[Either[MyError, Token]] = {
    import scala.concurrent.ExecutionContext.Implicits.global
    import scalacache.modes.scalaFuture._

    cachingF(clientCredentials)(ttl = Some(cacheConfig.cachingTime)) {
      defaultTokenRepository.fetchToken(clientCredentials)
    }

  }

I want to cache only Future(Right()) results.
Future.failed an Future(Left()) result shouldn't be cached and evaluated in next function call again.
Is there any way to provide logic which result of function evaluation should be stored in the cache?

Thank you for any suggestions!

Regards,
Sebastian

cb372 commented

I'm afraid this kind of conditional logic isn't possible with cachingF. You can do it by implementing the logic yourself using get and put, as shown in this gist.

A few people have asked similar questions before. Maybe the demand is high enough to warrant adding new combinators to the library to take care of this for you:

def condCaching[F[_], V, E](keyParts: Any*)
                           (ttl: Option[scala.concurrent.duration.Duration])
                           (f: => Either[E, V])
                           (implicit cache: scalacache.Cache[V],implicit mode: scalacache.Mode[F], implicit flags: scalacache.Flags): F[Either[E, V]]


def condCachingF[F[_], V, E](keyParts: Any*)
                           (ttl: Option[scala.concurrent.duration.Duration])
                           (f: => F[Either[E, V]])
                           (implicit cache: scalacache.Cache[V],implicit mode: scalacache.Mode[F], implicit flags: scalacache.Flags): F[Either[E, V]]

Alternatively you could achieve what you want by using EitherT from Cats or Scalaz. Your F[_] type would be EitherT[Future, MyError, ?]. But EitherT is not supported out of the box by ScalaCache, so you'd need to implement a new Mode for it.