-
Notifications
You must be signed in to change notification settings - Fork 508
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dispatcher: check for outstanding actions before release #3510
Dispatcher: check for outstanding actions before release #3510
Conversation
Co-authored-by: Daniel Spiewak <djspiewak@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Andrew, Sam, and I tripled to review this PR 😂 added some notes below.
We also produced a new test in 4374e98 that verifies that dispatchers "reject new tasks while shutting down"
. It is currently failing for some permutations, but may be fixable by setting alive
to false
before doing the final step(...)
in the release process.
This issue is relevant to this PR, since we want to be sure that the outstanding actions can't keep growing once we start the release process.
_ <- dispatcher.use { runner => IO(runner.unsafeRunAndForget(resultR.set(true))) } | ||
result <- resultR.get |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because of the race condition this test does not fail reliably for the parallel
dispatcher. We might want to run it for several iterations or used the ticked
runtime.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reran the test (without fix) a bunch of times but I couldn't reproduce the flake. I still rewrote using ticked
and also didn't see any flakes there so hopefully that is enough without running multiple times?
// published by release | ||
F.delay(doneR.lazySet(true)) *> release | ||
F.delay(doneR.lazySet(true)) *> step(states(n), F.unit) *> release |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if lazySet
makes sense anymore, since it's not immediately published by release
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, I don't think it makes sense. Now that we're doing work before the release, I think we want the doneR
value to be immediately available
// if we're marked as done, yield immediately to give other fibers a chance to shut us down | ||
// we might loop on this a few times since we're marked as done before the supervisor is canceled | ||
F.delay(doneR.get()).ifM(F.cede, step) | ||
F.delay(doneR.get()).ifM(F.cede, step(state, await)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tangential, but I wonder if we can complete this done
loop by returning a sentinel F[Unit]
value that the supervisor can use as indication that it should no longer restart this fiber.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I forgot to answer here :) When we talked about this it made sense to me, so I do want to try experimenting with that as a follow up!
Co-authored-by: Arman Bilge <armanbilge@gmail.com> Co-authored-by: Andrew Valencik <valencik@users.noreply.github.com>
Heads up: I have a draft PR up (#3521) with the |
The work on More details are in the writeup for #3521, but tldr:
The fix is moving the |
Sam points out that the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Super sorry for taking so long to get back to this! Trying to climb out of the hole I fell into…
Thank you for taking this on!
resolves #3506
c0ed15a adds a test demonstrating that a
Dispatcher
, withawait=true
, will finish without completing the effect (thus failing the test)Ultimately this is caused by the dispatcher finalizer running and releasing, even though there may have been new actions enqueued since the worker last checked.
Paired with @djspiewak and came to the solution in 0b6eaa4 in which we can now call
step
one last time, after the dispatcher is done but before releasing, so that those last-minute actions are forked appropriately. With this change the new test passes 🎉