Skip to content

feat: Add immediate:boolean to RunForkOptions - #1896

Merged
tim-smart merged 4 commits into
Effect-TS:next-minorfrom
TylorS:ts/feat/additional-runForkOptions
Jan 15, 2024
Merged

feat: Add immediate:boolean to RunForkOptions#1896
tim-smart merged 4 commits into
Effect-TS:next-minorfrom
TylorS:ts/feat/additional-runForkOptions

Conversation

@TylorS

@TylorSTylorS commented Jan 10, 2024

Copy link
Copy Markdown
Contributor

Type

  • Refactor
  • Feature
  • Bug Fix
  • Optimization
  • Documentation Update

Description

  • Adds immediate: boolean to RunForkOptions to enable creating a Fiber which uses fiberRuntime.start() or fiberRuntime.resume()

  • Adds RunCallbackOptions<E, A> which extends RunForkOptions with an onExit callback, such that runCallback has access to the same fork options as runFork.

Related

  • Related Issue #
  • Closes #

@changeset-bot

changeset-botBot commented Jan 10, 2024

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 426bdbb

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 17 packages
NameType
effectMinor
@effect/cliMajor
@effect/experimentalMajor
@effect/opentelemetryMajor
@effect/platform-browserMajor
@effect/platform-bunMajor
@effect/platform-nodeMajor
@effect/platformMajor
@effect/printer-ansiMajor
@effect/printerMajor
@effect/rpc-http-nodeMajor
@effect/rpc-httpMajor
@effect/rpc-nextjsMajor
@effect/rpc-workersMajor
@effect/rpcMajor
@effect/schemaMajor
@effect/typeclassMajor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@mattiamanzati

Copy link
Copy Markdown
Contributor

Bonus, could we please have this also on unsafeRunCallback? It is useful to have the callback eventually be called synchronously if the effect is sync as well

@TylorS

Copy link
Copy Markdown
ContributorAuthor

@mattiamanzati I should be able to add the immediate flag there as well. I'm going to remove the Scope option though, as it could lead to memory leaks if the surrounding scope is open indefinitely as the Fiber is never removed from the Scope upon exiting

@TylorS
TylorSforce-pushed the ts/feat/additional-runForkOptions branch 2 times, most recently from 917105e to 67952eeCompareJanuary 11, 2024 16:47
@TylorS
TylorS marked this pull request as ready for review January 11, 2024 16:49
@TylorS

Copy link
Copy Markdown
ContributorAuthor

@mattiamanzati Updated in the latest pushes

@mattiamanzati

Copy link
Copy Markdown
Contributor

@TylorS Thanks 🙏
Can't wait for this PR to be accepted and released!

@mikearnaldi

Copy link
Copy Markdown
Member

@mattiamanzati I should be able to add the immediate flag there as well. I'm going to remove the Scope option though, as it could lead to memory leaks if the surrounding scope is open indefinitely as the Fiber is never removed from the Scope upon exiting

Why would the fiber not being removed upon exit? that should be the behaviour

@TylorS

Copy link
Copy Markdown
ContributorAuthor

@mikearnaldi When you do Scope.addFinalizer(scope, Fiber.interrupt(fiber)), there is no corresponding API for removing the finalizer from the Scope after the Fiber exits. So if the scope it is being added to lives indefinitely (i.e. the scope of a React component's event listeners), the Fibers will be unable to be garbage collected due to being kept within the open Scope.

@mikearnaldi

Copy link
Copy Markdown
Member

@mikearnaldi When you do Scope.addFinalizer(scope, Fiber.interrupt(fiber)), there is no corresponding API for removing the finalizer from the Scope after the Fiber exits. So if the scope it is being added to lives indefinitely (i.e. the scope of a React component's event listeners), the Fibers will be unable to be garbage collected due to being kept within the open Scope.

you're right, I will investigate if adding an api to remove a finaliser may be useful

@TylorS

TylorS commented Jan 11, 2024

Copy link
Copy Markdown
ContributorAuthor

In the same vein, I'm not positive that forkIn or forkScoped are entirely safe. They do utilize forked Scope's which allows the Fiber to be garbage collected after completion, but there's a (albeit smaller) memory leak of child scopes if the parent scope is kept open indefinitely.

@TylorSTylorS changed the title feat: Add immediate:boolean & scope:Scope to RunForkOptionsfeat: Add immediate:boolean to RunForkOptionsJan 11, 2024
@mikearnaldi

Copy link
Copy Markdown
Member
/** @internal */exportconstforkIn=dual<(scope: Scope.Scope)=><R,E,A>(self: Effect.Effect<R,E,A>)=>Effect.Effect<R,never,Fiber.RuntimeFiber<E,A>>,<R,E,A>(self: Effect.Effect<R,E,A>,scope: Scope.Scope)=>Effect.Effect<R,never,Fiber.RuntimeFiber<E,A>>>(2,(self,scope)=>core.uninterruptibleMask((restore)=>core.flatMap(scope.fork(executionStrategy.sequential),(child)=>pipe(restore(self),core.onExit((exit)=>child.close(exit)),fiberRuntime.forkDaemon,core.tap((fiber)=>child.addFinalizer(()=>core.fiberIdWith((fiberId)=>Equal.equals(fiberId,fiber.id()) ?
core.unit :
core.asUnit(core.interruptFiber(fiber)))))))))

This is safe, it forks a separate scope and that scope is closed as the fiber ends

@TylorS

Copy link
Copy Markdown
ContributorAuthor

But closing that child/forked Scope doesn't remove its reference as a Finalizer in the parent Scope when it is closed

@TylorS

TylorS commented Jan 11, 2024

Copy link
Copy Markdown
ContributorAuthor

I take that back, I found the code that keeps it safe here - https://github.com/Effect-TS/effect/blob/main/packages/effect/src/internal/fiberRuntime.ts#L2962

Comment threadpackages/effect/src/Effect.ts
@TylorS
TylorSforce-pushed the ts/feat/additional-runForkOptions branch from 67952ee to 16bce8cCompareJanuary 12, 2024 03:31
@github-actions
github-actionsBot changed the base branch from main to next-minorJanuary 12, 2024 03:32
@tim-smart
tim-smart self-requested a review January 12, 2024 03:51
@tim-smart

Copy link
Copy Markdown
Contributor

Bonus, could we please have this also on unsafeRunCallback? It is useful to have the callback eventually be called synchronously if the effect is sync as well

The current behaviour is to start immediately, so you will see no change with this PR.

@mattiamanzati

Copy link
Copy Markdown
Contributor

Bonus, could we please have this also on unsafeRunCallback? It is useful to have the callback eventually be called synchronously if the effect is sync as well

The current behaviour is to start immediately, so you will see no change with this PR.

Uhm but run callback relies on run fork, so it should be affected as well right?

@TylorS

Copy link
Copy Markdown
ContributorAuthor

This PR enables non-immediate starts through immediate:false as the default is true to avoid breaking changes

@mattiamanzati

Copy link
Copy Markdown
Contributor

enables

Ohh, I though of it in the completely opposite direction.

@mikearnaldi

Copy link
Copy Markdown
Member

Can we add back Scope in the style used by forkIn? also it is worth updating the main runFork method in Effect.ts to take the RunOptions currently only Runtime exposes it

@TylorS

Copy link
Copy Markdown
ContributorAuthor

@mikearnaldi PR Updated with Scope here and the additional options to Effect.runFork here

Comment threadpackages/effect/src/internal/runtime.ts
@github-actions
github-actionsBotforce-pushed the next-minor branch 3 times, most recently from f723296 to ff47da4CompareJanuary 15, 2024 02:38
@tim-smart

Copy link
Copy Markdown
Contributor

@TylorS if you rebase that should fix CI

@TylorS
TylorSforce-pushed the ts/feat/additional-runForkOptions branch from 8215ce6 to 426bdbbCompareJanuary 15, 2024 03:18
@tim-smarttim-smart added the v3/next-minor Queues this PR for the next Effect V3 minor release. label Jan 15, 2024
@TylorS

Copy link
Copy Markdown
ContributorAuthor

Rebased

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v3/next-minorQueues this PR for the next Effect V3 minor release.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@TylorS@mattiamanzati@mikearnaldi@tim-smart