jpillora / overseer

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

Unable to terminate the program by sending a TERM signal to the main process #89

Open bourne-3 opened 1 year ago

bourne-3 commented 1 year ago

Context: I am using the Gin framework and have made some customizations to the framework. Here are some of the encapsulated structures.

type sm struct {
    *gin.Engine
    Server     *http.Server
    RouterFunc func(*gin.Engine)
    Config     WbConf
    Ln net.Listener
}

After completing all the initialization, the service is started using the following code:

func (ss *simpleServer) ListenAndServe() {
    if ss.Ln != nil {
        if err := ss.Engine.RunListener(ss.Ln); err != nil {
            fmt.Println("current listen err:", err)
            if !strings.Contains(err.Error(), "use of closed network connection") {
                logrus.WithError(err).Panic("InitServerStart() Mainserver ListenAndServe failed")
            }
        }
        return
    }

    ss.Server.Handler = ss.Engine
    if err := ss.Server.ListenAndServe(); err != nil {
        fmt.Println("current listen err:", err)
        if err != http.ErrServerClosed {
            logrus.WithError(err).Panic("InitServerStart() Mainserver ListenAndServe failed")
        }
    }
}

When using "overseer," I assign state.Listener to ss.Ln and then call ss.Engine.RunListener(ss.Ln) to start the service.

Problem: Currently, graceful restart is working fine. However, when I send a TERM signal to the program for a normal shutdown, it gets blocked and doesn't terminate.

image
image

How can I resolve the above issues?

bourne-3 commented 1 year ago

Update:

func (t *St) SH() {

    .... (some code)

    c := make(chan os.Signal, len(sigs))
    signal.Notify(c, sigs...)

    for {
        select {
        case sig := <-c:
            t.handle(sig)
        case <-t.ch:
            return
        }
    }
}

I found this function above in the code When I commented out this function, it closed properly ... Why this happen..?

bourne-3 commented 1 year ago

Also, I did an experiment and without any wrapping, with the default gin framework, when I call

kill -SIGUSR2 ${master_pid}

I get an error as follows

accept tcp [::]:5001: use of closed network connection

Is this error normal and do I need to deal with it?

====== Does this error report have the same effect as the http.ErrServerClosed ?

// ErrServerClosed is returned by the Server's Serve, ServeTLS, ListenAndServe,
// and ListenAndServeTLS methods after a call to Shutdown or Close.
var ErrServerClosed = errors.New("http: Server closed")