Skip to content

Commit b5bd22d

Browse files
Merge pull request #332 from nplevin/0.4-inf-loop-fix
Stop exceptions from causing an infinite loop.
2 parents c568174 + 83fa483 commit b5bd22d

File tree

1 file changed

+19
-6
lines changed

1 file changed

+19
-6
lines changed

modules/core/src/main/scala/io/chrisdavenport/mules/DispatchOneCache.scala

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,18 @@ final class DispatchOneCache[F[_], K, V] private[DispatchOneCache] (
6262
emptyFV
6363
}
6464

65-
private def insertAtomic(k: K, action: K => F[V]): F[Unit] = {
65+
private def insertAtomic(k: K, action: K => F[V]): F[Option[Either[Throwable, V]]] = {
6666
mapRef(k).modify{
6767
case None =>
6868
(None, createEmptyIfUnset(k))
6969
case s@Some(cacheItem) =>
7070
(s, updateIfFailedThenCreate(k, cacheItem))
7171
}.flatMap{ maybeDeferred =>
72-
maybeDeferred.bracketCase(_.traverse_{ deferred =>
73-
action(k).attempt.flatMap(e => deferred.complete(e).attempt.void)
72+
maybeDeferred.bracketCase(_.flatTraverse{ deferred =>
73+
action(k).attempt.flatMap(e => deferred.complete(e).attempt map {
74+
case Left(_) => Option.empty // Either.left[Throwable, V](err) //only happened if complete action fails
75+
case Right(_) => Option(e)
76+
})
7477
}){
7578
case (Some(deferred), ExitCase.Canceled) => deferred.complete(CancelationDuringDispatchOneCacheInsertProcessing.asLeft).attempt.void
7679
case (Some(deferred), ExitCase.Error(e)) => deferred.complete(e.asLeft).attempt.void
@@ -99,10 +102,20 @@ final class DispatchOneCache[F[_], K, V] private[DispatchOneCache] (
99102
}
100103
.flatMap{
101104
case Some(s) => s.item.get.flatMap{
102-
case Left(_) => insertAtomic(k, action) >> lookupOrLoad(k, action)
103-
case Right(v) => F.pure(v)
105+
case Left(_) => insertAtomic(k, action)
106+
case Right(v) => F.pure(Option(Either.right[Throwable,V](v)))
104107
}
105-
case None => insertAtomic(k, action) >> lookupOrLoad(k, action)
108+
case None => insertAtomic(k, action)
109+
}
110+
.flatMap {
111+
case Some(res) => res match {
112+
case Right(v) => v.pure[F]
113+
case Left(err) => err match {
114+
case CancelationDuringDispatchOneCacheInsertProcessing => lookupOrLoad(k,action)
115+
case _ => F.raiseError(err)
116+
}
117+
}
118+
case _ => lookupOrLoad(k,action) //cache miss case?
106119
}
107120
}
108121

0 commit comments

Comments
 (0)