Skip to content

Commit

Permalink
Merge branch 'arrow-2' into kyay10/autoclose-resource-rehaul
Browse files Browse the repository at this point in the history
  • Loading branch information
nomisRev committed May 18, 2024
2 parents 04103e8 + 0e22aa3 commit b15e29a
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ public final class arrow/fx/coroutines/ResourceKt {
public abstract interface class arrow/fx/coroutines/ResourceScope : arrow/AutoCloseScope {
public abstract fun bind (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public abstract fun onClose (Lkotlin/jvm/functions/Function1;)V
public abstract fun install (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public abstract fun onRelease (Lkotlin/jvm/functions/Function2;)V
public abstract fun release (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public abstract fun releaseCase (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -472,8 +472,28 @@ public suspend fun <A> Resource<A>.allocated(): Pair<A, suspend (ExitCase) -> Un
internal value class ResourceScopeImpl(
private val finalizers: Atomic<List<suspend (ExitCase) -> Unit>> = Atomic(emptyList()),
) : ResourceScope {
override fun onRelease(release: suspend (ExitCase) -> Unit) =
override suspend fun <A> Resource<A>.bind(): A = invoke(this@ResourceScopeImpl)

override fun onRelease(release: suspend (ExitCase) -> Unit) {
finalizers.update(release::prependTo)
}

override suspend fun <A> install(acquire: suspend AcquireStep.() -> A, release: suspend (A, ExitCase) -> Unit): A =
bracketCase({
val a = acquire(AcquireStep)
onRelease { ex: ExitCase -> release(a, ex) }
a
}, ::identity, { a, ex ->
// Only if ExitCase.Failure, or ExitCase.Cancelled during acquire we cancel
// Otherwise we've saved the finalizer, and it will be called from somewhere else.
if (ex != ExitCase.Completed) {
val e = cancelAll(ex)
val e2 = kotlin.runCatching { release(a, ex) }.exceptionOrNull()
e?.apply {
e2?.let(::addSuppressed)
}?.let { throw it }
}
})

suspend fun cancelAll(exitCase: ExitCase) {
withContext(NonCancellable) {
Expand Down

0 comments on commit b15e29a

Please sign in to comment.