github.com/astaxie/beego@v1.12.3/grace/grace.go (about) 1 // Copyright 2014 beego Author. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package grace use to hot reload 16 // Description: http://grisha.org/blog/2014/06/03/graceful-restart-in-golang/ 17 // 18 // Usage: 19 // 20 // import( 21 // "log" 22 // "net/http" 23 // "os" 24 // 25 // "github.com/astaxie/beego/grace" 26 // ) 27 // 28 // func handler(w http.ResponseWriter, r *http.Request) { 29 // w.Write([]byte("WORLD!")) 30 // } 31 // 32 // func main() { 33 // mux := http.NewServeMux() 34 // mux.HandleFunc("/hello", handler) 35 // 36 // err := grace.ListenAndServe("localhost:8080", mux) 37 // if err != nil { 38 // log.Println(err) 39 // } 40 // log.Println("Server on 8080 stopped") 41 // os.Exit(0) 42 // } 43 package grace 44 45 import ( 46 "flag" 47 "net/http" 48 "os" 49 "strings" 50 "sync" 51 "syscall" 52 "time" 53 ) 54 55 const ( 56 // PreSignal is the position to add filter before signal 57 PreSignal = iota 58 // PostSignal is the position to add filter after signal 59 PostSignal 60 // StateInit represent the application inited 61 StateInit 62 // StateRunning represent the application is running 63 StateRunning 64 // StateShuttingDown represent the application is shutting down 65 StateShuttingDown 66 // StateTerminate represent the application is killed 67 StateTerminate 68 ) 69 70 var ( 71 regLock *sync.Mutex 72 runningServers map[string]*Server 73 runningServersOrder []string 74 socketPtrOffsetMap map[string]uint 75 runningServersForked bool 76 77 // DefaultReadTimeOut is the HTTP read timeout 78 DefaultReadTimeOut time.Duration 79 // DefaultWriteTimeOut is the HTTP Write timeout 80 DefaultWriteTimeOut time.Duration 81 // DefaultMaxHeaderBytes is the Max HTTP Header size, default is 0, no limit 82 DefaultMaxHeaderBytes int 83 // DefaultTimeout is the shutdown server's timeout. default is 60s 84 DefaultTimeout = 60 * time.Second 85 86 isChild bool 87 socketOrder string 88 89 hookableSignals []os.Signal 90 ) 91 92 func init() { 93 flag.BoolVar(&isChild, "graceful", false, "listen on open fd (after forking)") 94 flag.StringVar(&socketOrder, "socketorder", "", "previous initialization order - used when more than one listener was started") 95 96 regLock = &sync.Mutex{} 97 runningServers = make(map[string]*Server) 98 runningServersOrder = []string{} 99 socketPtrOffsetMap = make(map[string]uint) 100 101 hookableSignals = []os.Signal{ 102 syscall.SIGHUP, 103 syscall.SIGINT, 104 syscall.SIGTERM, 105 } 106 } 107 108 // NewServer returns a new graceServer. 109 func NewServer(addr string, handler http.Handler) (srv *Server) { 110 regLock.Lock() 111 defer regLock.Unlock() 112 113 if !flag.Parsed() { 114 flag.Parse() 115 } 116 if len(socketOrder) > 0 { 117 for i, addr := range strings.Split(socketOrder, ",") { 118 socketPtrOffsetMap[addr] = uint(i) 119 } 120 } else { 121 socketPtrOffsetMap[addr] = uint(len(runningServersOrder)) 122 } 123 124 srv = &Server{ 125 sigChan: make(chan os.Signal), 126 isChild: isChild, 127 SignalHooks: map[int]map[os.Signal][]func(){ 128 PreSignal: { 129 syscall.SIGHUP: {}, 130 syscall.SIGINT: {}, 131 syscall.SIGTERM: {}, 132 }, 133 PostSignal: { 134 syscall.SIGHUP: {}, 135 syscall.SIGINT: {}, 136 syscall.SIGTERM: {}, 137 }, 138 }, 139 state: StateInit, 140 Network: "tcp", 141 terminalChan: make(chan error), //no cache channel 142 } 143 srv.Server = &http.Server{ 144 Addr: addr, 145 ReadTimeout: DefaultReadTimeOut, 146 WriteTimeout: DefaultWriteTimeOut, 147 MaxHeaderBytes: DefaultMaxHeaderBytes, 148 Handler: handler, 149 } 150 151 runningServersOrder = append(runningServersOrder, addr) 152 runningServers[addr] = srv 153 return srv 154 } 155 156 // ListenAndServe refer http.ListenAndServe 157 func ListenAndServe(addr string, handler http.Handler) error { 158 server := NewServer(addr, handler) 159 return server.ListenAndServe() 160 } 161 162 // ListenAndServeTLS refer http.ListenAndServeTLS 163 func ListenAndServeTLS(addr string, certFile string, keyFile string, handler http.Handler) error { 164 server := NewServer(addr, handler) 165 return server.ListenAndServeTLS(certFile, keyFile) 166 }