From bfe802734b450a4b4ee069d1125dd37995db2bff Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 25 Dec 2024 17:06:48 +1300 Subject: [PATCH] ensure Effect.timeoutTo sleep is interrupted (#4189) --- .changeset/modern-mice-battle.md | 5 + .../effect/src/internal/effect/circular.ts | 99 ++++++++++--------- 2 files changed, 57 insertions(+), 47 deletions(-) create mode 100644 .changeset/modern-mice-battle.md diff --git a/.changeset/modern-mice-battle.md b/.changeset/modern-mice-battle.md new file mode 100644 index 00000000000..d219323382f --- /dev/null +++ b/.changeset/modern-mice-battle.md @@ -0,0 +1,5 @@ +--- +"effect": patch +--- + +ensure Effect.timeoutTo sleep is interrupted diff --git a/packages/effect/src/internal/effect/circular.ts b/packages/effect/src/internal/effect/circular.ts index 51acf410943..0f41fad5fec 100644 --- a/packages/effect/src/internal/effect/circular.ts +++ b/packages/effect/src/internal/effect/circular.ts @@ -583,58 +583,63 @@ export const timeoutTo = dual< readonly duration: Duration.DurationInput } ) => Effect.Effect ->(2, (self, { duration, onSuccess, onTimeout }) => - core.fiberIdWith((parentFiberId) => - fiberRuntime.raceFibersWith( - self, - core.interruptible(effect.sleep(duration)), - { - onSelfWin: (winner, loser) => - core.flatMap( - winner.await, - (exit) => { - if (exit._tag === "Success") { - return core.flatMap( - winner.inheritAll, - () => - core.as( +>( + 2, + (self, { duration, onSuccess, onTimeout }) => + core.fiberIdWith((parentFiberId) => + core.uninterruptibleMask((restore) => + fiberRuntime.raceFibersWith( + restore(self), + core.interruptible(effect.sleep(duration)), + { + onSelfWin: (winner, loser) => + core.flatMap( + winner.await, + (exit) => { + if (exit._tag === "Success") { + return core.flatMap( + winner.inheritAll, + () => + core.as( + core.interruptAsFiber(loser, parentFiberId), + onSuccess(exit.value) + ) + ) + } else { + return core.flatMap( core.interruptAsFiber(loser, parentFiberId), - onSuccess(exit.value) + () => core.exitFailCause(exit.cause) ) - ) - } else { - return core.flatMap( - core.interruptAsFiber(loser, parentFiberId), - () => core.exitFailCause(exit.cause) - ) - } - } - ), - onOtherWin: (winner, loser) => - core.flatMap( - winner.await, - (exit) => { - if (exit._tag === "Success") { - return core.flatMap( - winner.inheritAll, - () => - core.as( + } + } + ), + onOtherWin: (winner, loser) => + core.flatMap( + winner.await, + (exit) => { + if (exit._tag === "Success") { + return core.flatMap( + winner.inheritAll, + () => + core.as( + core.interruptAsFiber(loser, parentFiberId), + onTimeout() + ) + ) + } else { + return core.flatMap( core.interruptAsFiber(loser, parentFiberId), - onTimeout() + () => core.exitFailCause(exit.cause) ) - ) - } else { - return core.flatMap( - core.interruptAsFiber(loser, parentFiberId), - () => core.exitFailCause(exit.cause) - ) - } - } - ), - otherScope: globalScope - } + } + } + ), + otherScope: globalScope + } + ) + ) ) - )) +) // circular with Synchronized