Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@adamgfraser
Copy link
Contributor

Resolves #4116.

It looks like the issue here is that we are getting interrupted when attempting to close the scope of the child fiber. The child fiber tries to close its scope after it finishes forking the grandchild but then is externally interrupted. As a result, the finalizers in its scope are never run and so we do not wait for the interruption of the grandchild to return.

ghostdogpr
ghostdogpr previously approved these changes Aug 20, 2020
*/
if (!state.compareAndSet(oldState, Executing(oldStatus.toFinishing, observers, interrupted))) done(v)
else openScope.close(v) *> ZIO.done(v)
else openScope.close(v).uninterruptible *> ZIO.done(v)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if it is interrupted before the openScope.close(v) begins execution?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. Maybe we need to use unsafeClose here?

mikearnaldi added a commit to Effect-TS/effect that referenced this pull request Aug 24, 2020
@jdegoes
Copy link
Member

jdegoes commented Aug 25, 2020

@adamgfraser Let's pair on this since I think it will be quite tricky.

@adamgfraser
Copy link
Contributor Author

@jdegoes That would be great!

jdegoes
jdegoes previously approved these changes Sep 3, 2020

oldState match {
case Executing(Status.Suspended(oldStatus, true, _, _, _), observers, interrupted) =>
case Executing(Status.Suspended(oldStatus, true, _, _, _), observers, interrupted) if !oldState.interrupting =>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a race condition in if !oldState.interrupting. I think it's ok.

We may want to add a test for this if one doesn't exist, basically that async finalizers during winddown can't be interrupted. Could be tested with a latch.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, can you say more about this?

We're getting the interrupting status from the old state so we're working off of one consistent snapshot of the state at a single point in time.

If the interrupting status gets changed to true while we executing then the compareAndSet will return false and we will loop again, at which point interrupting will be true so we won't do anything here.

So we are relying on whatever other fiber changed the interrupting status to true to actually do the interruption since this fiber won't. Is that right?

Can definitely work on adding a test for this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kill is called from other fibers, so what happens if the fiber itself changes the state of setInterrupting to false at the same time this check is happening. In this case, this code here (in kill) will make a different decision about what to do based on the changing boolean value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. Then state would not be equal to oldState and we would loop and then on the next loop interrupting would be false and we would interrupt. But isn't that the behavior we want? You're definitely right there can be a race between setting the interrupting status and interrupting but I think with this whatever the interrupting status is when the compareAndSet gets evaluated will control which seems correct.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a test for this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, you're right, because you are looking at oldState.interrupting, which will be consistent with the state.

Good with me. 👍

@adamgfraser adamgfraser merged commit 3950efa into zio:master Sep 3, 2020
heaven-born pushed a commit to heaven-born/zio that referenced this pull request Sep 8, 2020
* close scope uninterruptibly

* prevent interruption before close begins execution

* add test

* revert
heaven-born added a commit to heaven-born/zio that referenced this pull request Sep 8, 2020
@adamgfraser adamgfraser deleted the 4116 branch September 28, 2020 17:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Auto-supervision doesn't wait for nested fibers

3 participants