Application Shutdown Handler

477 views
Skip to first unread message

Si Robertson

unread,
Sep 26, 2014, 1:02:22 AM9/26/14
to golan...@googlegroups.com
Hi guys,

Is there anyway to handle a forced shutdown of a Go application?

When I say "forced" I mean the application process being terminated before the main function has returned. I have tried a deferred function call from main but that doesn't work, probably due to the fact main never returns during a forced shutdown.

func main() {
    defer shutdown()
    // do lots of cool things
}

// never gets invoked during a forced shutdown.
func shutdown() {
    // handle things gracefully here
}

Thanks.

Jesse McNelis

unread,
Sep 26, 2014, 1:49:45 AM9/26/14
to Si Robertson, golang-nuts
On Fri, Sep 26, 2014 at 3:02 PM, Si Robertson <retrom...@gmail.com> wrote:
> Hi guys,
>
> Is there anyway to handle a forced shutdown of a Go application?

http://golang.org/pkg/os/signal/

You listen for the signal and do the thing you want to do before exiting.

Steve McCoy

unread,
Sep 26, 2014, 9:49:39 AM9/26/14
to golan...@googlegroups.com
Write your program so that it can work without this, because you cannot be sure you'll receive a "nice" kill signal.

Si Robertson

unread,
Sep 26, 2014, 10:18:22 AM9/26/14
to golan...@googlegroups.com
The kill signal isn't working for me anyway (running Windows 7 if that makes a difference), the app never receives a signal if the parent console window is closed while the app is running. I haven't tried a forced shutdown from the task manager yet.

Go apps really need a mechanism to deal with this though, just like "normal" apps. I think it would be possible on Windows by spawning a console window (or even a regular window) and handling the incoming system messages in a message loop, but obviously that means branching the code for different platforms which isn't ideal.

James Bardin

unread,
Sep 26, 2014, 10:35:27 AM9/26/14
to golan...@googlegroups.com


On Friday, September 26, 2014 10:18:22 AM UTC-4, Si Robertson wrote:
The kill signal isn't working for me anyway (running Windows 7 if that makes a difference), the app never receives a signal if the parent console window is closed while the app is running. I haven't tried a forced shutdown from the task manager yet.


Well, if by "kill", you mean SIGKILL you can't catch that (at least in POSIX). Did you try the usual signals like HUP, or TERM?
 
Go apps really need a mechanism to deal with this though, just like "normal" apps. I think it would be possible on Windows by spawning a console window (or even a regular window) and handling the incoming system messages in a message loop, but obviously that means branching the code for different platforms which isn't ideal.


What's a "normal" app, and how does it handle the closing of a terminal window? IIRC there's some sort of mechanism in windows to register a handler with your parent window which you could probably access through SWIG or cgo.

Si Robertson

unread,
Sep 26, 2014, 11:08:11 AM9/26/14
to golan...@googlegroups.com
I'm using the signals documented in the Go package reference (http://golang.org/pkg/os/#Signal), and the code is based on the provided example. Apparently those signals are guaranteed to be present on all systems but the docs do not say those signals are guaranteed to be caught (received by the Go app).

In "normal" apps created with C/C++ etc we would be dealing with a message pump or a console CTRL handler, at least on Windows systems.

It looks like this is going to require platform-specific code in the Go app as I mentioned previously.

Ibrahim M. Ghazal

unread,
Sep 26, 2014, 11:33:44 AM9/26/14
to Si Robertson, golang-nuts
On Fri, Sep 26, 2014 at 6:08 PM, Si Robertson <retrom...@gmail.com> wrote:
> I'm using the signals documented in the Go package reference
> (http://golang.org/pkg/os/#Signal), and the code is based on the provided
> example. Apparently those signals are guaranteed to be present on all
> systems but the docs do not say those signals are guaranteed to be caught
> (received by the Go app).
>
> In "normal" apps created with C/C++ etc we would be dealing with a message
> pump or a console CTRL handler, at least on Windows systems.
>
> It looks like this is going to require platform-specific code in the Go app
> as I mentioned previously.
>

If I'm reading the sources correctly, on Windows, signals are emulated
by SetConsoleCtrlHandler (see
https://code.google.com/p/go/source/browse/src/runtime/os_windows.c#484
). It handles CTRL_C_EVENT and CTRL_BREAK_EVENT as SIGINT.

Closing the console window sends a CTRL_CLOSE_EVENT and gives the
program 5 seconds before killing it. As far as I can tell, the Go
runtime doesn't handle CTRL_CLOSE_EVENT. Perhaps it should handle it
as SIGHUP or some other signal?

Si Robertson

unread,
Sep 26, 2014, 11:54:31 AM9/26/14
to golan...@googlegroups.com, retrom...@gmail.com
That looks like the problem right there, thanks Ibrahim :)

Ctrl+C on Windows does indeed cause a signal to be fired, so I'm going to hack my local Go installation to see if I can get the CTRL_CLOSE event to also trigger a signal. If that works I will post another reply here and also get in touch with the Go guys to see if CTRL_CLOSE can be implemented at their end.

Ibrahim M. Ghazal

unread,
Sep 26, 2014, 12:14:04 PM9/26/14
to golang-nuts
On Fri, Sep 26, 2014 at 6:32 PM, Ibrahim M. Ghazal <img...@gmail.com> wrote:
> If I'm reading the sources correctly, on Windows, signals are emulated
> by SetConsoleCtrlHandler (see
> https://code.google.com/p/go/source/browse/src/runtime/os_windows.c#484
> ). It handles CTRL_C_EVENT and CTRL_BREAK_EVENT as SIGINT.
>
> Closing the console window sends a CTRL_CLOSE_EVENT and gives the
> program 5 seconds before killing it. As far as I can tell, the Go
> runtime doesn't handle CTRL_CLOSE_EVENT. Perhaps it should handle it
> as SIGHUP or some other signal?

Just for fun, I dived into the Java source code to see how it handles
it. Apparently, it handles CTRL_CLOSE_EVENT as SIGTERM. See:
http://hg.openjdk.java.net/jdk9/dev/hotspot/file/9b3f5e4f3372/src/os/windows/vm/os_windows.cpp#l1883
.

I still think SIGHUP is a more sensible choice, though.

Chris Hines

unread,
Sep 26, 2014, 12:42:31 PM9/26/14
to golan...@googlegroups.com
There is already an issue for this, see https://code.google.com/p/go/issues/detail?id=6948.

But even if that gets implemented, Steve McCoy is correct in saying you shouldn't rely on always getting these signals.

On *nix "kill -9" and "TerminateProcess()" in the Windows API both stop a process abruptly with no chance of interception by the target.

Si Robertson

unread,
Sep 26, 2014, 1:29:17 PM9/26/14
to golan...@googlegroups.com
I spotted this issue as well:

Yep, there are some edge cases where these signals would be of no use but something is better than nothing at all. Closing a console using the standard GUI buttons (on Windows) is a common thing to do.

Rolf

unread,
Sep 28, 2014, 8:04:36 PM9/28/14
to golan...@googlegroups.com
FYI For those who want a code example for use in their Go server using signal.Notify(syscall.SIGTERM,  etcetera).
Not for Windows nor kill -9 as discussed before.


On Friday, September 26, 2014 7:02:22 AM UTC+2, Si Robertson wrote:
Hi guys,

Is there anyway to handle a forced shutdown of a Go application?

Thanks.

brainman

unread,
Sep 28, 2014, 9:46:37 PM9/28/14
to golan...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages