Skip to content

Commit

Permalink
Merge pull request #5 from davenverse/allowSynchronousPersistence
Browse files Browse the repository at this point in the history
Allow Synchronous Persistence
  • Loading branch information
ChristopherDavenport authored Sep 2, 2022
2 parents 3e93b61 + d9a852c commit b66bd56
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,25 @@ private[snickerdoodle] object SnCookieJar {
private[snickerdoodle] class Http4sPersistenceCookieJarImpl[F[_]: Concurrent: Clock](
persistence: SnCookiePersistence[F],
supervisor: Supervisor[F],
synchronousPersistence: Boolean,
ref: Ref[F, Map[SnCookie.SnCookieKey, SnCookie]],
isPublicSuffix: String => Boolean
) extends CookieJar[F]{

def persist[A](fa: F[A]): F[Unit] = {
if (synchronousPersistence) fa.void
else supervisor.supervise(fa).void
}

def evictExpired: F[Unit] = for {
now <- HttpDate.current[F].map(_.epochSecond)
_ <- ref.update(_.filter(t => now <= t._2.expiry))
_ <- supervisor.supervise(persistence.clearExpired(now))
_ <- persist(persistence.clearExpired(now))
} yield ()

def evictAll: F[Unit] =
ref.set(Map.empty) >>
persistence.clear
ref.set(Map.empty) >>
persist(persistence.clear)

def addCookies[G[_]: Foldable](cookies: G[(ResponseCookie, Uri)]): F[Unit] =
for {
Expand All @@ -36,7 +43,7 @@ private[snickerdoodle] object SnCookieJar {
snO.fold(m)(v => m + v)
}
_ <- ref.update(m => m ++ map)
_ <- supervisor.supervise(map.toList.traverse_{ case (_, c) => if (c.persist) persistence.create(c) else Applicative[F].unit}).void
_ <- persist(map.toList.traverse_{ case (_, c) => if (c.persist) persistence.create(c) else Applicative[F].unit}).void
} yield ()

def enrichRequest[G[_]](r: Request[G]): F[Request[G]] = for {
Expand All @@ -51,7 +58,7 @@ private[snickerdoodle] object SnCookieJar {
}
(m ++ updatedMap, filtered)
}
_ <- supervisor.supervise(cookies.traverse_(c => if (c.persist) persistence.updateLastAccessed(SnCookie.SnCookieKey.fromCookie(c), c.lastAccessed) else Applicative[F].unit))
_ <- persist(cookies.traverse_(c => if (c.persist) persistence.updateLastAccessed(SnCookie.SnCookieKey.fromCookie(c), c.lastAccessed) else Applicative[F].unit))
} yield cookies.foldLeft(r){ case (r, c) => r.addCookie(SnCookie.toRequestCookie(c))}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ final class SnCookieJarBuilder[F[_]: Async] private (
private val supervisorO: Option[Supervisor[F]],
private val persistenceO: Option[Resource[F, SnCookiePersistence[F]]],
private val isPublicSuffixO: Option[Resource[F, String => Boolean]],
){ self =>
private val synchronousPersistence: Boolean,
){ self =>
def copy(
supervisorO: Option[Supervisor[F]] = self.supervisorO,
persistenceO: Option[Resource[F, SnCookiePersistence[F]]] = self.persistenceO,
isPublicSuffixO: Option[Resource[F, String => Boolean]] = self.isPublicSuffixO
): SnCookieJarBuilder[F] = new SnCookieJarBuilder[F](supervisorO, persistenceO, isPublicSuffixO)
isPublicSuffixO: Option[Resource[F, String => Boolean]] = self.isPublicSuffixO,
synchronousPersistence: Boolean = self.synchronousPersistence
): SnCookieJarBuilder[F] = new SnCookieJarBuilder[F](supervisorO, persistenceO, isPublicSuffixO, synchronousPersistence)

def withSupervisor(s: Supervisor[F]) = copy(supervisorO = s.some)

Expand All @@ -24,6 +26,9 @@ final class SnCookieJarBuilder[F[_]: Async] private (
def withPersistence(c: SnCookiePersistence[F]) =
copy(persistenceO = c.pure[Resource[F, *]].some)

def withSynchronousPersistence = copy(synchronousPersistence = true)
def withAsynchronousPersistence = copy(synchronousPersistence = false)

def withoutPersistence = copy(persistenceO = None)

def withIsPublicSuffix(f: String => Boolean) = copy(isPublicSuffixO = f.pure[Resource[F, *]].some)
Expand All @@ -44,7 +49,7 @@ final class SnCookieJarBuilder[F[_]: Async] private (
)
)
isPublicSuffix <- isPublicSuffixO.getOrElse({(_: String) => false}.pure[Resource[F, *]])
out = tO.fold[CookieJar[F]](new SnCookieJar.Http4sMemoryCookieJarImpl[F](state, isPublicSuffix)){ case (cp, s) => new SnCookieJar.Http4sPersistenceCookieJarImpl[F](cp, s, state, isPublicSuffix)}
out = tO.fold[CookieJar[F]](new SnCookieJar.Http4sMemoryCookieJarImpl[F](state, isPublicSuffix)){ case (cp, s) => new SnCookieJar.Http4sPersistenceCookieJarImpl[F](cp, s, synchronousPersistence, state, isPublicSuffix)}
_ <- Resource.eval(out.evictExpired)
} yield out

Expand All @@ -66,16 +71,17 @@ final class SnCookieJarBuilder[F[_]: Async] private (
)
)
isPublicSuffix <- isPublicSuffixO.getOrElse({(_: String) => false}.pure[Resource[F, *]])
cj = tO.fold[CookieJar[F]](new SnCookieJar.Http4sMemoryCookieJarImpl[F](state, isPublicSuffix)){ case (cp, s) => new SnCookieJar.Http4sPersistenceCookieJarImpl[F](cp, s, state, isPublicSuffix)}
cj = tO.fold[CookieJar[F]](new SnCookieJar.Http4sMemoryCookieJarImpl[F](state, isPublicSuffix)){ case (cp, s) => new SnCookieJar.Http4sPersistenceCookieJarImpl[F](cp, s, synchronousPersistence, state, isPublicSuffix)}
_ <- Resource.eval(cj.evictExpired)
} yield (cj, state)
}
}

object SnCookieJarBuilder {
def default[F[_]: Async]: SnCookieJarBuilder[F] = new SnCookieJarBuilder[F](None, None, Defaults.isPublicSuffix)
def default[F[_]: Async]: SnCookieJarBuilder[F] = new SnCookieJarBuilder[F](None, None, Defaults.isPublicSuffix, Defaults.synchronousPersistence)

private object Defaults extends SnCookieJarBuilderDefaultsPlaftom {
val synchronousPersistence = true

}
}

0 comments on commit b66bd56

Please sign in to comment.