I tried tried using sync.WaitGroup with the handlers; however this did not
resolve the problem. If you look at the net/http/server.go http.conn.serve()
method, you can see the handler is called towards the end. After the handler
returns, it proceeds to finish the request and wrap up the connection. This
means that, even after all handlers have finished, exiting main can prematurely
terminate the http.conn.serve() goroutines.
My solution for this was to simply write a net.Listener and net.Conn wrapper
which would keep track of open connections. Once the listener is closed, main
simply waits for the remaining connections to be closed.
Closing the server through closing the connection seems like pulling the carpet
beneat its feet. I think some sort of method for gracefully stopping the
server would be a great addition.