mirror of
https://github.com/astaxie/beego.git
synced 2024-12-22 18:50:50 +00:00
golint grace
This commit is contained in:
parent
01a5e54264
commit
65fb7ce391
@ -4,7 +4,7 @@ import "net"
|
||||
|
||||
type graceConn struct {
|
||||
net.Conn
|
||||
server *graceServer
|
||||
server *Server
|
||||
}
|
||||
|
||||
func (c graceConn) Close() error {
|
||||
|
@ -12,6 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package grace use to hot reload
|
||||
// Description: http://grisha.org/blog/2014/06/03/graceful-restart-in-golang/
|
||||
//
|
||||
// Usage:
|
||||
@ -52,26 +53,36 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
PRE_SIGNAL = iota
|
||||
POST_SIGNAL
|
||||
// PreSignal is the position to add filter before signal
|
||||
PreSignal = iota
|
||||
// PostSignal is the position to add filter after signal
|
||||
PostSignal
|
||||
|
||||
STATE_INIT
|
||||
STATE_RUNNING
|
||||
STATE_SHUTTING_DOWN
|
||||
STATE_TERMINATE
|
||||
// StateInit represent the application inited
|
||||
StateInit
|
||||
// StateRunning represent the application is running
|
||||
StateRunning
|
||||
// StateShuttingDown represent the application is shutting down
|
||||
StateShuttingDown
|
||||
// StateTerminate represent the application is killed
|
||||
StateTerminate
|
||||
)
|
||||
|
||||
var (
|
||||
regLock *sync.Mutex
|
||||
runningServers map[string]*graceServer
|
||||
runningServers map[string]*Server
|
||||
runningServersOrder []string
|
||||
socketPtrOffsetMap map[string]uint
|
||||
runningServersForked bool
|
||||
|
||||
DefaultReadTimeOut time.Duration
|
||||
DefaultWriteTimeOut time.Duration
|
||||
// DefaultReadTimeOut is the HTTP read timeout
|
||||
DefaultReadTimeOut time.Duration
|
||||
// DefaultWriteTimeOut is the HTTP Write timeout
|
||||
DefaultWriteTimeOut time.Duration
|
||||
// DefaultMaxHeaderBytes is the Max HTTP Herder size, default is 0, no limit
|
||||
DefaultMaxHeaderBytes int
|
||||
DefaultTimeout time.Duration
|
||||
// DefaultTimeout is the shutdown server's timeout. default is 60s
|
||||
DefaultTimeout time.Duration
|
||||
|
||||
isChild bool
|
||||
socketOrder string
|
||||
@ -81,7 +92,7 @@ func init() {
|
||||
regLock = &sync.Mutex{}
|
||||
flag.BoolVar(&isChild, "graceful", false, "listen on open fd (after forking)")
|
||||
flag.StringVar(&socketOrder, "socketorder", "", "previous initialization order - used when more than one listener was started")
|
||||
runningServers = make(map[string]*graceServer)
|
||||
runningServers = make(map[string]*Server)
|
||||
runningServersOrder = []string{}
|
||||
socketPtrOffsetMap = make(map[string]uint)
|
||||
|
||||
@ -91,7 +102,7 @@ func init() {
|
||||
}
|
||||
|
||||
// NewServer returns a new graceServer.
|
||||
func NewServer(addr string, handler http.Handler) (srv *graceServer) {
|
||||
func NewServer(addr string, handler http.Handler) (srv *Server) {
|
||||
regLock.Lock()
|
||||
defer regLock.Unlock()
|
||||
if !flag.Parsed() {
|
||||
@ -105,23 +116,23 @@ func NewServer(addr string, handler http.Handler) (srv *graceServer) {
|
||||
socketPtrOffsetMap[addr] = uint(len(runningServersOrder))
|
||||
}
|
||||
|
||||
srv = &graceServer{
|
||||
srv = &Server{
|
||||
wg: sync.WaitGroup{},
|
||||
sigChan: make(chan os.Signal),
|
||||
isChild: isChild,
|
||||
SignalHooks: map[int]map[os.Signal][]func(){
|
||||
PRE_SIGNAL: map[os.Signal][]func(){
|
||||
PreSignal: map[os.Signal][]func(){
|
||||
syscall.SIGHUP: []func(){},
|
||||
syscall.SIGINT: []func(){},
|
||||
syscall.SIGTERM: []func(){},
|
||||
},
|
||||
POST_SIGNAL: map[os.Signal][]func(){
|
||||
PostSignal: map[os.Signal][]func(){
|
||||
syscall.SIGHUP: []func(){},
|
||||
syscall.SIGINT: []func(){},
|
||||
syscall.SIGTERM: []func(){},
|
||||
},
|
||||
},
|
||||
state: STATE_INIT,
|
||||
state: StateInit,
|
||||
Network: "tcp",
|
||||
}
|
||||
srv.Server = &http.Server{}
|
||||
@ -137,13 +148,13 @@ func NewServer(addr string, handler http.Handler) (srv *graceServer) {
|
||||
return
|
||||
}
|
||||
|
||||
// refer http.ListenAndServe
|
||||
// ListenAndServe refer http.ListenAndServe
|
||||
func ListenAndServe(addr string, handler http.Handler) error {
|
||||
server := NewServer(addr, handler)
|
||||
return server.ListenAndServe()
|
||||
}
|
||||
|
||||
// refer http.ListenAndServeTLS
|
||||
// ListenAndServeTLS refer http.ListenAndServeTLS
|
||||
func ListenAndServeTLS(addr string, certFile string, keyFile string, handler http.Handler) error {
|
||||
server := NewServer(addr, handler)
|
||||
return server.ListenAndServeTLS(certFile, keyFile)
|
||||
|
@ -11,10 +11,10 @@ type graceListener struct {
|
||||
net.Listener
|
||||
stop chan error
|
||||
stopped bool
|
||||
server *graceServer
|
||||
server *Server
|
||||
}
|
||||
|
||||
func newGraceListener(l net.Listener, srv *graceServer) (el *graceListener) {
|
||||
func newGraceListener(l net.Listener, srv *Server) (el *graceListener) {
|
||||
el = &graceListener{
|
||||
Listener: l,
|
||||
stop: make(chan error),
|
||||
@ -46,17 +46,17 @@ func (gl *graceListener) Accept() (c net.Conn, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (el *graceListener) Close() error {
|
||||
if el.stopped {
|
||||
func (gl *graceListener) Close() error {
|
||||
if gl.stopped {
|
||||
return syscall.EINVAL
|
||||
}
|
||||
el.stop <- nil
|
||||
return <-el.stop
|
||||
gl.stop <- nil
|
||||
return <-gl.stop
|
||||
}
|
||||
|
||||
func (el *graceListener) File() *os.File {
|
||||
func (gl *graceListener) File() *os.File {
|
||||
// returns a dup(2) - FD_CLOEXEC flag *not* set
|
||||
tl := el.Listener.(*net.TCPListener)
|
||||
tl := gl.Listener.(*net.TCPListener)
|
||||
fl, _ := tl.File()
|
||||
return fl
|
||||
}
|
||||
|
@ -15,7 +15,8 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type graceServer struct {
|
||||
// Server embedded http.Server
|
||||
type Server struct {
|
||||
*http.Server
|
||||
GraceListener net.Listener
|
||||
SignalHooks map[int]map[os.Signal][]func()
|
||||
@ -30,19 +31,19 @@ type graceServer struct {
|
||||
// Serve accepts incoming connections on the Listener l,
|
||||
// creating a new service goroutine for each.
|
||||
// The service goroutines read requests and then call srv.Handler to reply to them.
|
||||
func (srv *graceServer) Serve() (err error) {
|
||||
srv.state = STATE_RUNNING
|
||||
func (srv *Server) Serve() (err error) {
|
||||
srv.state = StateRunning
|
||||
err = srv.Server.Serve(srv.GraceListener)
|
||||
log.Println(syscall.Getpid(), "Waiting for connections to finish...")
|
||||
srv.wg.Wait()
|
||||
srv.state = STATE_TERMINATE
|
||||
srv.state = StateTerminate
|
||||
return
|
||||
}
|
||||
|
||||
// ListenAndServe listens on the TCP network address srv.Addr and then calls Serve
|
||||
// to handle requests on incoming connections. If srv.Addr is blank, ":http" is
|
||||
// used.
|
||||
func (srv *graceServer) ListenAndServe() (err error) {
|
||||
func (srv *Server) ListenAndServe() (err error) {
|
||||
addr := srv.Addr
|
||||
if addr == "" {
|
||||
addr = ":http"
|
||||
@ -83,7 +84,7 @@ func (srv *graceServer) ListenAndServe() (err error) {
|
||||
// CA's certificate.
|
||||
//
|
||||
// If srv.Addr is blank, ":https" is used.
|
||||
func (srv *graceServer) ListenAndServeTLS(certFile, keyFile string) (err error) {
|
||||
func (srv *Server) ListenAndServeTLS(certFile, keyFile string) (err error) {
|
||||
addr := srv.Addr
|
||||
if addr == "" {
|
||||
addr = ":https"
|
||||
@ -131,9 +132,9 @@ func (srv *graceServer) ListenAndServeTLS(certFile, keyFile string) (err error)
|
||||
|
||||
// getListener either opens a new socket to listen on, or takes the acceptor socket
|
||||
// it got passed when restarted.
|
||||
func (srv *graceServer) getListener(laddr string) (l net.Listener, err error) {
|
||||
func (srv *Server) getListener(laddr string) (l net.Listener, err error) {
|
||||
if srv.isChild {
|
||||
var ptrOffset uint = 0
|
||||
var ptrOffset uint
|
||||
if len(socketPtrOffsetMap) > 0 {
|
||||
ptrOffset = socketPtrOffsetMap[laddr]
|
||||
log.Println("laddr", laddr, "ptr offset", socketPtrOffsetMap[laddr])
|
||||
@ -157,7 +158,7 @@ func (srv *graceServer) getListener(laddr string) (l net.Listener, err error) {
|
||||
|
||||
// handleSignals listens for os Signals and calls any hooked in function that the
|
||||
// user had registered with the signal.
|
||||
func (srv *graceServer) handleSignals() {
|
||||
func (srv *Server) handleSignals() {
|
||||
var sig os.Signal
|
||||
|
||||
signal.Notify(
|
||||
@ -170,7 +171,7 @@ func (srv *graceServer) handleSignals() {
|
||||
pid := syscall.Getpid()
|
||||
for {
|
||||
sig = <-srv.sigChan
|
||||
srv.signalHooks(PRE_SIGNAL, sig)
|
||||
srv.signalHooks(PreSignal, sig)
|
||||
switch sig {
|
||||
case syscall.SIGHUP:
|
||||
log.Println(pid, "Received SIGHUP. forking.")
|
||||
@ -187,11 +188,11 @@ func (srv *graceServer) handleSignals() {
|
||||
default:
|
||||
log.Printf("Received %v: nothing i care about...\n", sig)
|
||||
}
|
||||
srv.signalHooks(POST_SIGNAL, sig)
|
||||
srv.signalHooks(PostSignal, sig)
|
||||
}
|
||||
}
|
||||
|
||||
func (srv *graceServer) signalHooks(ppFlag int, sig os.Signal) {
|
||||
func (srv *Server) signalHooks(ppFlag int, sig os.Signal) {
|
||||
if _, notSet := srv.SignalHooks[ppFlag][sig]; !notSet {
|
||||
return
|
||||
}
|
||||
@ -204,12 +205,12 @@ func (srv *graceServer) signalHooks(ppFlag int, sig os.Signal) {
|
||||
// shutdown closes the listener so that no new connections are accepted. it also
|
||||
// starts a goroutine that will serverTimeout (stop all running requests) the server
|
||||
// after DefaultTimeout.
|
||||
func (srv *graceServer) shutdown() {
|
||||
if srv.state != STATE_RUNNING {
|
||||
func (srv *Server) shutdown() {
|
||||
if srv.state != StateRunning {
|
||||
return
|
||||
}
|
||||
|
||||
srv.state = STATE_SHUTTING_DOWN
|
||||
srv.state = StateShuttingDown
|
||||
if DefaultTimeout >= 0 {
|
||||
go srv.serverTimeout(DefaultTimeout)
|
||||
}
|
||||
@ -224,26 +225,26 @@ func (srv *graceServer) shutdown() {
|
||||
// serverTimeout forces the server to shutdown in a given timeout - whether it
|
||||
// finished outstanding requests or not. if Read/WriteTimeout are not set or the
|
||||
// max header size is very big a connection could hang
|
||||
func (srv *graceServer) serverTimeout(d time.Duration) {
|
||||
func (srv *Server) serverTimeout(d time.Duration) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Println("WaitGroup at 0", r)
|
||||
}
|
||||
}()
|
||||
if srv.state != STATE_SHUTTING_DOWN {
|
||||
if srv.state != StateShuttingDown {
|
||||
return
|
||||
}
|
||||
time.Sleep(d)
|
||||
log.Println("[STOP - Hammer Time] Forcefully shutting down parent")
|
||||
for {
|
||||
if srv.state == STATE_TERMINATE {
|
||||
if srv.state == StateTerminate {
|
||||
break
|
||||
}
|
||||
srv.wg.Done()
|
||||
}
|
||||
}
|
||||
|
||||
func (srv *graceServer) fork() (err error) {
|
||||
func (srv *Server) fork() (err error) {
|
||||
regLock.Lock()
|
||||
defer regLock.Unlock()
|
||||
if runningServersForked {
|
||||
|
Loading…
Reference in New Issue
Block a user