-
Notifications
You must be signed in to change notification settings - Fork 5.3k
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
Up: teardown when command context is cancelled #11292
Conversation
Looks like |
95800a7
to
2ff71b9
Compare
`AdaptCmd` was previously checking for a `.WithCancel` suffix on context strings, however it's possible for a context to be cancellable without ending in that suffix, such as when `context.WithValue` was called after `WithContext`, e.g.: ```go context.Background.WithCancel.WithValue(type trace.traceContextKeyType, val <not Stringer>).WithValue(type api.DryRunKey, val <not Stringer>) ``` Signed-off-by: Laura Brehm <laurabrehm@hey.com>
2ff71b9
to
0a3cc5f
Compare
cmd/compose/compose.go
Outdated
@@ -277,7 +278,12 @@ const PluginName = "compose" | |||
|
|||
// RunningAsStandalone detects when running as a standalone program | |||
func RunningAsStandalone() bool { |
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.
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.
Agree! 😅
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #11292 +/- ##
==========================================
- Coverage 56.36% 56.22% -0.15%
==========================================
Files 134 135 +1
Lines 11615 11659 +44
==========================================
+ Hits 6547 6555 +8
- Misses 4421 4451 +30
- Partials 647 653 +6 ☔ View full report in Codecov by Sentry. |
Previously, if a long-lived plugin process (such as an execution of `compose up`) was running and then detached from a terminal, signalling the parent CLI process to exit would leave the plugin process behind. To address this, changes were introduced on the CLI side (see: docker/cli#4599) to enable the CLI to notify a running plugin process that it should exit. This makes it so that, when the parent CLI process is going to exit, the command context of the plugin command being executed is cancelled. This commit takes advantage of these changes by tapping into the command context's done channel and using it to teardown on an up. Signed-off-by: Laura Brehm <laurabrehm@hey.com>
0a3cc5f
to
dcbf005
Compare
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.
LGTM
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.
LGTM, and you're my hero for fixing this!
I tested standalone, with Compose CLI trampoline, and with Docker CLI and all looks good. (Well, the standalone case does return exit code 130 but that's not a new regression; I'll open a quick PR for that later.)
Changes were made in docker#4599 to provide a mechanism for the CLI to notify running plugin processes that they should exit, in order to improve the general CLI/plugin UX. The current implementation boils down to: 1. The CLI creates a socket 2. The CLI executes the plugin 3. The plugin connects to the socket 4. (When) the CLI receives a termination signal, it uses the socket to notify the plugin that it should exit 5. The plugin's gets notified via the socket, and cancels it's `cmd.Context`, which then gets handled appropriately This change works in most cases and fixes the issue it sets out to solve (see: docker/compose#11292) however, in the case where the user has a TTY attached and the plugin is not already handling received signals, steps 4+ changes: 4. (When) the CLI receives a termination signal, before it can use the socket to notify the plugin that it should exit, the plugin process also receives a signal due to sharing the pgid with the CLI Since we now have a proper "job control" mechanism, we can simplify the scenarios by executing the plugins with their own process group id, thereby removing the "double notification" issue and making it so that plugins can handle the same whether attached to a TTY or not. In order to make this change "plugin-binary" backwards-compatible, in the case that a plugin does not connect to the socket, the CLI passes the signal to the plugin process. Signed-off-by: Laura Brehm <laurabrehm@hey.com>
Changes were made in docker#4599 to provide a mechanism for the CLI to notify running plugin processes that they should exit, in order to improve the general CLI/plugin UX. The current implementation boils down to: 1. The CLI creates a socket 2. The CLI executes the plugin 3. The plugin connects to the socket 4. (When) the CLI receives a termination signal, it uses the socket to notify the plugin that it should exit 5. The plugin's gets notified via the socket, and cancels it's `cmd.Context`, which then gets handled appropriately This change works in most cases and fixes the issue it sets out to solve (see: docker/compose#11292) however, in the case where the user has a TTY attached and the plugin is not already handling received signals, steps 4+ changes: 4. (When) the CLI receives a termination signal, before it can use the socket to notify the plugin that it should exit, the plugin process also receives a signal due to sharing the pgid with the CLI Since we now have a proper "job control" mechanism, we can simplify the scenarios by executing the plugins with their own process group id, thereby removing the "double notification" issue and making it so that plugins can handle the same whether attached to a TTY or not. In order to make this change "plugin-binary" backwards-compatible, in the case that a plugin does not connect to the socket, the CLI passes the signal to the plugin process. Signed-off-by: Laura Brehm <laurabrehm@hey.com>
Changes were made in docker#4599 to provide a mechanism for the CLI to notify running plugin processes that they should exit, in order to improve the general CLI/plugin UX. The current implementation boils down to: 1. The CLI creates a socket 2. The CLI executes the plugin 3. The plugin connects to the socket 4. (When) the CLI receives a termination signal, it uses the socket to notify the plugin that it should exit 5. The plugin's gets notified via the socket, and cancels it's `cmd.Context`, which then gets handled appropriately This change works in most cases and fixes the issue it sets out to solve (see: docker/compose#11292) however, in the case where the user has a TTY attached and the plugin is not already handling received signals, steps 4+ changes: 4. (When) the CLI receives a termination signal, before it can use the socket to notify the plugin that it should exit, the plugin process also receives a signal due to sharing the pgid with the CLI Since we now have a proper "job control" mechanism, we can simplify the scenarios by executing the plugins with their own process group id, thereby removing the "double notification" issue and making it so that plugins can handle the same whether attached to a TTY or not. In order to make this change "plugin-binary" backwards-compatible, in the case that a plugin does not connect to the socket, the CLI passes the signal to the plugin process. Signed-off-by: Laura Brehm <laurabrehm@hey.com>
Changes were made in 1554ac3 to provide a mechanism for the CLI to notify running plugin processes that they should exit, in order to improve the general CLI/plugin UX. The current implementation boils down to: 1. The CLI creates a socket 2. The CLI executes the plugin 3. The plugin connects to the socket 4. (When) the CLI receives a termination signal, it uses the socket to notify the plugin that it should exit 5. The plugin's gets notified via the socket, and cancels it's `cmd.Context`, which then gets handled appropriately This change works in most cases and fixes the issue it sets out to solve (see: docker/compose#11292) however, in the case where the user has a TTY attached and the plugin is not already handling received signals, steps 4+ changes: 4. (When) the CLI receives a termination signal, before it can use the socket to notify the plugin that it should exit, the plugin process also receives a signal due to sharing the pgid with the CLI Since we now have a proper "job control" mechanism, we can simplify the scenarios by executing the plugins with their own process group id, thereby removing the "double notification" issue and making it so that plugins can handle the same whether attached to a TTY or not. In order to make this change "plugin-binary" backwards-compatible, in the case that a plugin does not connect to the socket, the CLI passes the signal to the plugin process. Co-authored-by: Bjorn Neergaard <bjorn.neergaard@docker.com> Signed-off-by: Laura Brehm <laurabrehm@hey.com> Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
What I did
Previously, if a long-lived plugin process (such as an execution of
compose up
) was running and then detached from a terminal, signalling the parent CLI process to exit would leave the plugin process behind.To address this, changes were introduced on the CLI side (see: docker/cli#4599) to enable the CLI to notify a running plugin process that it should exit. This makes it so that, when the parent CLI process is going to exit, the command context of the plugin command being executed is cancelled.
This PR takes advantage of that change by using that channel on an
up
to know when to teardown.Also fixed the "cancellable context" detection in
cmd/compose/compose.go
, as the string suffix matching was missing contexts such as:Before:
Screen.Recording.2023-12-20.at.17.40.21.mov
After:
Screen.Recording.2023-12-20.at.17.43.07.mov
Related issue
docker/cli#4599
(not mandatory) A picture of a cute animal, if possible in relation to what you did