0

I'm referring to this article: Graceful Shutdowns on Cloud Run

The example outlines how to do this in Node.js.

How would one do this in Golang? Any issues with simply adding this to the func init() method?

func shutdownGracefully() {
    c := make(chan os.Signal)
    signal.Notify(c, os.Interrupt, syscall.SIGTERM)
    go func() {
        <-c
        // Do some cleanup stuff here...

        os.Exit(0)
    }()
}
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Jan Krynauw
  • 1,042
  • 10
  • 21
  • That should work, have you tried trying it? – Adrian Mar 29 '21 at 13:28
  • yes, it seems to work, just wanted to check if that there are no side-effects relating to Cloud Run instance terminations - i.e. could a 'background' goroutine stop an instance from terminating or are termination purely driven by received requests? – Jan Krynauw Mar 29 '21 at 13:46
  • 1
    The first paragraph of the page you linked seems pretty clear. If the container does not exit, it will be terminated after 10 seconds. There's no such thing as a "background goroutine"; all goroutines are equal, and when `main()` returns, the program exits and all its goroutines end. – Adrian Mar 29 '21 at 14:24

2 Answers2

2

We have sample Go code for proper signal handling at https://github.com/GoogleCloudPlatform/golang-samples/pull/1902. It's not merged yet but essentially highlights how to do this properly on Go.

Beware that when running locally, sending Ctrl+C to your application is a SIGINT, however on Cloud Run you will be getting SIGTERM. It is also important to pass cancellations properly and handling server shutdown gracefully while not dropping the ongoing requests (though, net/http.Server handles a decent portion of this for you as you’ll see in sample code).

ahmet alp balkan
  • 42,679
  • 38
  • 138
  • 214
0

How would one do this in Golang?

An idiomatic way to handle graceful shutdowns in go is having a select statement blocking the main goroutine listening for any signal. From there you can trigger all the proper shutdowns when necessary.

For instance:

select {
case err := <-anyOtherError:
    // ...
case signal := <- c:
    // Handle shutdown e.g. like http Server Shutdown
}

I like to set it inside a run function with other startup tasks like starting the server, configs, etc.

Rick
  • 159
  • 1
  • 5