Skip to content
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

Fix goroutine leak on closing #259

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

ItalyPaleAle
Copy link
Member

It appears that these goroutines do not receive the context, so the scheduler keeps running even after shutdown

Copy link
Member

@richardpark-msft richardpark-msft left a comment

Choose a reason for hiding this comment

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

We'd need to think about this a bit more. My concern is mostly about the scope of the cancellation.

In StartNonBlocking, the function call will have returned. If someone cancels the context after StartNonBlocking returns they'll end up cancelling their already started processor. That feels like unexpected new behavior. We do provide a way for them to do that properly (with Close()) so I think we'd want to stick with that.

I think we could argue that Start() should work properly with a cancellation context, however. Looking at it some more I think we'd need to do a bit more work to check the cancellation context + the signalChan, but otherwise it could be fine. However, I'm still worried that people that assumed they could cancel the context and not affect anything will be surprised, but maybe it wouldn't be so bad there.

@jhendrixMSFT, what do you think about this?

@ItalyPaleAle
Copy link
Member Author

If someone cancels the context after StartNonBlocking returns they'll end up cancelling their already started processor.

Got it, although that's how contexts are supposed to be used, as a way to cancel background processes.

I know that a "track2" of this SDK is in the works so perhaps spending too much time optimizing this isn't even worth it at this point.

@richardpark-msft
Copy link
Member

If someone cancels the context after StartNonBlocking returns they'll end up cancelling their already started processor.

Got it, although that's how contexts are supposed to be used, as a way to cancel background processes.

Yeah, it's a good point. I can see it both ways - do you expect to keep the context to still apply long past the call being "complete" though? It seems like it's supposed to be considered safe to just cancel it after the function call returns, but in this case you'd still end up cancelling the .Run().

I know that a "track2" of this SDK is in the works so perhaps spending too much time optimizing this isn't even worth it at this point.

This is true, but your point is 100% valid so I'd like to make sure, if we have do something similar, that our design makes sense to other Go people.

@richardpark-msft
Copy link
Member

@ItalyPaleAle, all of what I wrote above only applies to the non-blocking version of the call. The blocking version makes sense to me.

@ItalyPaleAle
Copy link
Member Author

do you expect to keep the context to still apply long past the call being "complete" though?

IMHO, yes. Usually, when a method accepts a context and runs in background, the context is the cancellation signal.

@jhendrixMSFT
Copy link
Member

I'm also a bit worried that if we change the behavior now it will break somebody that depends on it.

Given that a track 2 replacement is on the way, I'd prefer if we just document this behavior instead. We'll improve the API for track 2. Does that work @ItalyPaleAle for you?

@ItalyPaleAle
Copy link
Member Author

Yes that makes sense.

In the meanwhile, is there a way to fix the goroutine leak without breaking changes? For example, adding another context that is started inside StartNonBlocking and stopped on Close?

avoid goroutine leak when Close() is called
@jhendrixMSFT
Copy link
Member

Agreed that should be fixed. I made some changes to your PR. Let me know if it works for you.

@ItalyPaleAle
Copy link
Member Author

@jhendrixMSFT thanks for the changes! (To my limited knowledge) LGTM :)

@jhendrixMSFT
Copy link
Member

If @richardpark-msft approves I'll get it merged and tagged.

@@ -83,6 +85,9 @@ func (s *scheduler) Run(ctx context.Context) {
case <-ctx.Done():
s.dlog(ctx, "shutting down scan")
return
case <-s.close:
Copy link
Member

Choose a reason for hiding this comment

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

In line 188, we actually call the s.done() function, which cancels the context we used to spin up this entire thing. So I think this s.close is not needed.

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.

3 participants