braintree / manners

A polite Go HTTP server that shuts down gracefully.
MIT License
997 stars 103 forks source link

A blocking version of Close() #31

Closed xlab closed 8 years ago

xlab commented 9 years ago

Hello, I recently discovered this package and found out that its Close() method doesn't block. I have a helper package github.com/xlab/closer that calls functions upon app's exit, so as soon as all the "cleanup" functions are done it closes the app with os.Exit().

I've tried to use that package with manners and the result is quite ugly:

func main() {
    // start the http server
    server := manners.NewWithServer(&http.Server{Addr: ":8080", Handler: nil})

    // a channel to check on exit that ListenAndServe is done
    exitChan := make(chan struct{})
    closer.Bind(func() {
        <-exitChan
    })
    // bind server.Close to be called if app is exiting because of a signal
    closer.Bind(func() {
        server.Close()
    })
    if err := server.ListenAndServe(); err != nil {
        log.Fatalln(err)
    }
    close(exitChan)
}

As you can see, I've been forced to add an additional channel that will ensure blocking for the graceful shutdown circuit. Instead of this (only 1 additional line of code) doing the same thing:

func main() {
    server := manners.NewWithServer(&http.Server{Addr: ":8080", Handler: nil})
    closer.Bind(func() { server.BlockingClose() }) // that's it!
    server.ListenAndServe()
}

Adopted practice

Many services that offer graceful shutdown feature either provide a blocking close method or a channel one could listen to. Example of channel: nsq.Consumer

type Consumer struct {

    // read from this channel to block until consumer is cleanly stopped
    StopChan chan int
    // contains filtered or unexported fields
}

// Stop will initiate a graceful stop of the Consumer (permanent)
//
// NOTE: receive on StopChan to block until this process completes
func (r *Consumer) Stop()
xlab commented 8 years ago

Any ideas? Should I implement this by myself? Will it be pulled?

lionelbarrow commented 8 years ago

Good idea -- added in https://github.com/braintree/manners/commit/cab36f97339b1925cd89e158632728025557e550