@@ -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