jpillora / overseer

Monitorable, gracefully restarting, self-upgrading binaries in Go (golang)
MIT License
2.33k stars 209 forks source link

Using a go routine does not keep the connection alive #35

Open lookfirst opened 5 years ago

lookfirst commented 5 years ago

Using a go routine does not keep the connection alive.

  1. compile program.
  2. telnet to port 3000
  3. kill -s SIGUSR2 PID

If you do this same program without the go routine wrapper, the connection is not dropped.

package main

import (
        "fmt"
        "log"
        "net/http"

        "github.com/jpillora/overseer"
)

//create another main() to run the overseer process
//and then convert your old main() into a 'prog(state)'
func main() {
        overseer.Run(overseer.Config{
                Debug: true,
                Program: prog,
                Address: ":3000",
        })
}

//prog(state) runs in a child process
func prog(state overseer.State) {
        log.Printf("app (%s) listening...", state.ID)
        http.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
                fmt.Fprintf(w, "app (%s) says hello\n", state.ID)
        }))
        go func() {
                if err := http.Serve(state.Listener, nil); err != nil {
                     log.Println(err)
                }
        }()
        <-state.GracefulShutdown
}
lookfirst commented 5 years ago

Ah, I think I understand now. The issue is that normally the state.Listener, which gets converted into a overseeerListener would block being closed, so the connection remains open. But if it is run in a go routine, that blocking doesn't happen. I wonder how to make that happen still.

The issue is that I would like to be able to start up multiple listeners and have zero downtime restarts.