Skip to content

Commit

Permalink
simplify async constructors (#1715)
Browse files Browse the repository at this point in the history
  • Loading branch information
tim-smart authored Nov 29, 2023
1 parent 8a1e98c commit 8b1a7e8
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 46 deletions.
5 changes: 5 additions & 0 deletions .changeset/cool-foxes-press.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"effect": patch
---

only add onInterrupt in Effect.async if required
5 changes: 5 additions & 0 deletions .changeset/quiet-turkeys-bake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"effect": patch
---

simplify Effect.tryCatch implementation
55 changes: 26 additions & 29 deletions src/internal/core-effect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1629,7 +1629,6 @@ export const tryPromise: {
): Effect.Effect<never, E | Cause.UnknownException, A> => {
let evaluate: (signal?: AbortSignal) => Promise<A>
let catcher: ((error: unknown) => E) | undefined = undefined

if (typeof arg === "function") {
evaluate = arg as (signal?: AbortSignal) => Promise<A>
} else {
Expand All @@ -1638,40 +1637,38 @@ export const tryPromise: {
}

if (evaluate.length >= 1) {
return core.suspend(() => {
const controller = new AbortController()
return core.flatMap(try_(() => evaluate(controller.signal)), (promise) =>
core.async((resolve) => {
promise
.then((a) => resolve(core.exitSucceed(a)))
.catch((e) =>
resolve(core.fail(
catcher ? catcher(e) : new core.UnknownException(e)
))
)
return core.sync(() => controller.abort())
}))
})
}

return core.flatMap(
try_(
arg as {
readonly try: LazyArg<Promise<A>>
readonly catch: (error: unknown) => E
}
),
(promise) =>
core.async((resolve) => {
promise
return core.async((resolve, signal) => {
try {
evaluate(signal)
.then((a) => resolve(core.exitSucceed(a)))
.catch((e) =>
resolve(core.fail(
catcher ? catcher(e) : new core.UnknownException(e)
))
)
})
)
} catch (e) {
resolve(core.fail(
catcher ? catcher(e) : new core.UnknownException(e)
))
}
})
}

return core.async((resolve) => {
try {
evaluate()
.then((a) => resolve(core.exitSucceed(a)))
.catch((e) =>
resolve(core.fail(
catcher ? catcher(e) : new core.UnknownException(e)
))
)
} catch (e) {
resolve(core.fail(
catcher ? catcher(e) : new core.UnknownException(e)
))
}
})
}

/* @internal */
Expand Down
47 changes: 30 additions & 17 deletions src/internal/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -439,28 +439,41 @@ export const async = <R, E, A>(
blockingOn: FiberId.FiberId = FiberId.none
): Effect.Effect<R, E, A> =>
suspend(() => {
let backingResume: ((_: Effect.Effect<R, E, A>) => void) | undefined = undefined
let pendingEffect: Effect.Effect<R, E, A> | undefined = undefined
function proxyResume(effect: Effect.Effect<R, E, A>) {
if (backingResume) {
backingResume(effect)
} else if (pendingEffect === undefined) {
pendingEffect = effect
}
}
const effect = new EffectPrimitive(OpCodes.OP_ASYNC) as any
effect.i0 = (resume: (_: Effect.Effect<R, E, A>) => void) => {
backingResume = resume
if (pendingEffect) {
resume(pendingEffect)
}
}
effect.i1 = blockingOn

let cancelerRef: Effect.Effect<R, never, void> | void = undefined
let controllerRef: AbortController | void = undefined
const effect = new EffectPrimitive(OpCodes.OP_ASYNC) as any
if (register.length !== 1) {
const controller = new AbortController()
controllerRef = controller
effect.i0 = (resume: (_: Effect.Effect<R, E, A>) => void) => {
cancelerRef = register(resume, controller.signal)
}
controllerRef = new AbortController()
cancelerRef = register(proxyResume, controllerRef.signal)
} else {
effect.i0 = (resume: (_: Effect.Effect<R, E, A>) => void) => {
// @ts-expect-error
cancelerRef = register(resume)
}
cancelerRef = (register as any)(proxyResume)
}
effect.i1 = blockingOn
return onInterrupt(effect, () => {
if (controllerRef) {
controllerRef.abort()
}
return cancelerRef ?? unit
})

return (cancelerRef || controllerRef) ?
onInterrupt(effect, (_) => {
if (controllerRef) {
controllerRef.abort()
}
return cancelerRef ?? unit
}) :
effect
})

/* @internal */
Expand Down

0 comments on commit 8b1a7e8

Please sign in to comment.