All Downloads are FREE. Search and download functionalities are using the official Maven repository.

me.wojnowski.oidc4s.impure.AtomicRefCache.scala Maven / Gradle / Ivy

package me.wojnowski.oidc4s.impure

import cats.Monad
import cats.effect.Clock
import cats.syntax.all._
import me.wojnowski.oidc4s.Cache
import me.wojnowski.oidc4s.Cache.DefaultExpiration
import me.wojnowski.oidc4s.Cache.Entry

import java.util.concurrent.atomic.AtomicReference
import scala.concurrent.duration.FiniteDuration

case class AtomicRefCache[F[_]: Monad: Clock, A](defaultExpiration: FiniteDuration = DefaultExpiration) extends Cache[F, A] {
  // Used directly instead of cats.effect.Ref[], as this particular use
  // does not seem to require Sync[F]
  private val configRef = new AtomicReference[Option[Entry[A]]](None)

  override def get: F[Option[A]] =
    for {
      now <- Clock[F].realTimeInstant
      maybeEntry = configRef.get
    } yield maybeEntry.filter(_.expiresAt.isAfter(now)).map(_.value)

  override def put(config: A, expiresIn: Option[FiniteDuration]): F[Unit] =
    Clock[F].realTimeInstant.map { now =>
      val expiresAt = now.plusNanos(expiresIn.getOrElse(defaultExpiration).toNanos)
      configRef.updateAndGet {
        case Some(entry) if entry.expiresAt.isAfter(expiresAt) =>
          Some(entry)
        case _                                                 =>
          Some(Entry(config, expiresAt))
      }
      ()
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy