-
Notifications
You must be signed in to change notification settings - Fork 305
TestDataRace: Fix leak #1081
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
Merged
Merged
TestDataRace: Fix leak #1081
+1
−1
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
TestDataRace never calls App.Stop, which can cause a resource leak. This currently passes because of the implementation detail that Shutdowner.Shutdown happens to call signalReceivers.Stop instead of just Shutdown, which may not always be true.
Codecov Report
@@ Coverage Diff @@
## master #1081 +/- ##
=======================================
Coverage 98.53% 98.53%
=======================================
Files 39 39
Lines 2997 2997
=======================================
Hits 2953 2953
Misses 37 37
Partials 7 7 📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
abhinav
added a commit
to abhinav/fx
that referenced
this pull request
May 6, 2023
Shutdowner.Shutdown is not a blocking operation. It does not need to block and wait for the relay goroutine to stop; signalReceiver.Stop will do that. To clarify this further, signalReceivers has the following operations: - Start: starts a relay goroutine - Stop: stops the relay goroutine and waits for it - Wait: create and return a `chan ShutdownSignal` - Done: create and return a `chan os.Signal` - Broadcast: Send the message to all waiting channels The only reason that the relay goroutine exists is to map `os.Signal`s received by `os/signal.Notify` into an `fx.ShutdownSignal`. Shutdowner.Shutdown should not call signalReceivers.Stop because the relay goroutine should keep running so that we can re-use Shutdowner.Shutdown. This change exposed a leak in TestDataRace (fixed in uber-go#1081).
sywhang
approved these changes
May 8, 2023
sywhang
added a commit
that referenced
this pull request
May 8, 2023
Stacked on top of: - #1081 However, since I can't push branches directly to this repository, this PR shows commits from both PRs. --- Shutdowner.Shutdown is not a blocking operation. It does not need to block and wait for the relay goroutine to stop; signalReceiver.Stop will do that. To clarify this further, signalReceivers has the following operations: - Start: starts a relay goroutine - Stop: stops the relay goroutine and waits for it - Wait: create and return a `chan ShutdownSignal` - Done: create and return a `chan os.Signal` - Broadcast: Send the message to all waiting channels The only reason that the relay goroutine exists is to map `os.Signal`s received by `os/signal.Notify` into an `fx.ShutdownSignal`. Shutdowner.Shutdown should not call signalReceivers.Stop because the relay goroutine should keep running so that we can re-use Shutdowner.Shutdown. This change exposed a leak in TestDataRace (fixed in #1081). --------- Co-authored-by: Sung Yoon Whang <sungyoon@uber.com>
sywhang
added a commit
that referenced
this pull request
May 8, 2023
Stacked on top of: - #1081 - #1082 However, since I can't push branches directly to this repository, this PR shows commits from all PRs. --- App.Start nils out the "last" signal recorded by signalReceivers, which it otherwise broadcasts to waiters if it was already received. This is unnecessary especially because there's a discrepancy in behavior of using App.Start vs App.Run when shutting down from fx.Invoke. Given a program that calls Shutdown from fx.Invoke, when we do: app := fx.New(...) The shutdowner has already sent the signal, and signalReceivers has already recorded it. At that point, whether we call App.Start or App.Run changes behavior: - If we call App.Run, that calls App.Done (or App.Wait after #1075), which gives it back a channel that already has the signal filled in. It then calls App.Start, waits on the channel--which returns immediately--and then calls App.Stop. - If we call App.Start and App.Wait, on the other hand, Start will clear the signal recorded in signalReceivers, and then App.Wait will build a channel that will block indefinitely because Shutdowner.Shutdown will not be called again. So even though App.Run() and App.Start()+App.Wait() are meant to be equivalent, this causes a serious discrepancy in behavior. It makes sense to resolve this by supporting Shutdown from Invoke. Refs #1074 --------- Co-authored-by: Sung Yoon Whang <sungyoon@uber.com>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
TestDataRace never calls App.Stop, which can cause a resource leak.
This currently passes because of the implementation detail that
Shutdowner.Shutdown happens to call signalReceivers.Stop
instead of just Shutdown, which may not always be true.