Skip to content

os/signal: add NotifyContext function #37255

Closed
@henvic

Description

@henvic

As previously discussed on issues such as #21521 and #16472, or on several other places handling POSIX signals through context seems to be somewhat useful (and a little bit hard to do correctly?), and I would like to propose a way to handle it by adding a new signal.WithContext function.

There's also an idea to improve the current approach to handling signals (see #21521 (comment)). I didn't give it a try yet, unfortunately. I only found the earlier proposals here after trying to write some code, so I decided to create this new issue anyway to share my idea.

People using some sort of it or talking about the subject:

Activity

added this to the Proposal milestone on Feb 17, 2020
gopherbot

gopherbot commented on Feb 17, 2020

@gopherbot
Contributor

Change https://golang.org/cl/219640 mentions this issue: os/signal: add WithContext to control single usage signals easily.

henvic

henvic commented on Feb 17, 2020

@henvic
ContributorAuthor

Also please notice that this change would, unfortunately, require introducing packages time and context as dependencies for package os/signal.

changed the title [-]proposal: signal.WithContext[/-] [+]proposal: os/signal: add WithContext function[/+] on Feb 17, 2020
ianlancetaylor

ianlancetaylor commented on Feb 17, 2020

@ianlancetaylor
Contributor

Could you describe the new function in this issue, so that we don't have to figure it out from the CL? Thanks.

henvic

henvic commented on Feb 17, 2020

@henvic
ContributorAuthor

The new function receives a parent context and a variadic number of signals that can be used to cancel this context. When a parent context is canceled or when one of the signals is handled, the context is canceled.

Example of handling cancelation of a slow process through SIGTERM and SIGINT:

func main() {
	ctx, cancel := signal.WithContext(context.Background(), syscall.SIGTERM, syscall.SIGINT)
	defer cancel()

	// ...
	slow.Run(ctx)
	cancel()

	// to verify if the slow function was terminated by a signal, we can use:
	var sigErr signal.ContextError
	if errors.As(ctx.Err(), &sigErr) {
		fmt.Printf("slow function terminated by signal %q\n")
	}
}

On another side, we have the example shown for https://golang.org/pkg/net/http/#Server.Shutdown that, in my opinion, would not be simplified by this.

robpike

robpike commented on Feb 17, 2020

@robpike
Contributor

Perhaps this should be a function of the context package instead, since it creates a context and it's pretty much all about contexts.

ctx, cancel := context.Signal(context.Background(), syscall.SIGTERM, syscall.SIGINT)

Not sure it's the right idea at all, just throwing it out there.

mattn

mattn commented on Feb 17, 2020

@mattn
Member

If several packages handle same signal, and runtime does not handle those contexts equally, context.Signal won't work correctly, I think. If runtime does not handle them, context.Signals is not best way . The os/signal package has the potential feeling for us that it is only used in applications, but the context package is used by everyone. So I'm thinking signal.WithContext is better since it make users known that we should do it in only one place. (But I'm also not sure this is right idea)

rsc

rsc commented on Mar 11, 2020

@rsc
Contributor

To be clear, the runtime does already broadcast signals to anyone who has signed up to hear about them, using signal.Notify. So this could be done as a separate package without worrying about other possible uses of os/signal.

context.WithCancelSignal seems like the clearest name, and it would appear right next to context.WithCancel in the docs.

/cc @Sajmani for thoughts

changed the title [-]proposal: os/signal: add WithContext function[/-] [+]proposal: context: add WithCancelSignal function[/+] on Mar 25, 2020
rsc

rsc commented on Mar 25, 2020

@rsc
Contributor

It sounds like maybe we have converged on context.WithCancelSignal. I've retitled.
Based on the discussion above, this seems like a likely accept.

henvic

henvic commented on Mar 27, 2020

@henvic
ContributorAuthor

Great! Thanks for the feedback. I'll try to send a new CL proposing an implementation for a context.WithCancelSignal command Monday.

49 remaining items

changed the title [-]proposal: os/signal: add NotifyContext function[/-] [+]os/signal: add NotifyContext function[/+] on May 20, 2020
danp

danp commented on Aug 31, 2020

@danp
Contributor

@henvic Were you planning to adapt your CL (or a new one) based on the change to os/signal.NotifyContext? I'd be happy to help however I can, would be great to get this in for 1.16.

henvic

henvic commented on Sep 14, 2020

@henvic
ContributorAuthor

@danp, thank you for the help!

Hello @ianlancetaylor, might you please take a second look at the updated CL? I have sent a new patchset. Thank you!

https://go-review.googlesource.com/c/go/+/219640

locked and limited conversation to collaborators on Sep 15, 2021
moved this to Accepted in Proposalson Aug 10, 2022
removed this from Proposalson Oct 19, 2022
added a commit that references this issue on Apr 29, 2024
b6dbaef
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @danp@mattn@rogpeppe@narqo@rsc

        Issue actions

          os/signal: add NotifyContext function · Issue #37255 · golang/go