mirror of
https://github.com/astaxie/beego.git
synced 2024-11-25 18:50:55 +00:00
beego: delete hotupdate
This commit is contained in:
parent
3f2a712ba8
commit
04290dfc68
1
admin.go
1
admin.go
@ -107,7 +107,6 @@ func listConf(rw http.ResponseWriter, r *http.Request) {
|
|||||||
fmt.Fprintln(rw, "MaxMemory:", MaxMemory)
|
fmt.Fprintln(rw, "MaxMemory:", MaxMemory)
|
||||||
fmt.Fprintln(rw, "EnableGzip:", EnableGzip)
|
fmt.Fprintln(rw, "EnableGzip:", EnableGzip)
|
||||||
fmt.Fprintln(rw, "DirectoryIndex:", DirectoryIndex)
|
fmt.Fprintln(rw, "DirectoryIndex:", DirectoryIndex)
|
||||||
fmt.Fprintln(rw, "EnableHotUpdate:", EnableHotUpdate)
|
|
||||||
fmt.Fprintln(rw, "HttpServerTimeOut:", HttpServerTimeOut)
|
fmt.Fprintln(rw, "HttpServerTimeOut:", HttpServerTimeOut)
|
||||||
fmt.Fprintln(rw, "ErrorsShow:", ErrorsShow)
|
fmt.Fprintln(rw, "ErrorsShow:", ErrorsShow)
|
||||||
fmt.Fprintln(rw, "XSRFKEY:", XSRFKEY)
|
fmt.Fprintln(rw, "XSRFKEY:", XSRFKEY)
|
||||||
|
77
app.go
77
app.go
@ -45,7 +45,7 @@ func (app *App) Run() {
|
|||||||
err error
|
err error
|
||||||
l net.Listener
|
l net.Listener
|
||||||
)
|
)
|
||||||
endRunning := make(chan bool)
|
endRunning := make(chan bool, 1)
|
||||||
|
|
||||||
if UseFcgi {
|
if UseFcgi {
|
||||||
if HttpPort == 0 {
|
if HttpPort == 0 {
|
||||||
@ -58,56 +58,35 @@ func (app *App) Run() {
|
|||||||
}
|
}
|
||||||
err = fcgi.Serve(l, app.Handlers)
|
err = fcgi.Serve(l, app.Handlers)
|
||||||
} else {
|
} else {
|
||||||
if EnableHotUpdate {
|
s := &http.Server{
|
||||||
server := &http.Server{
|
Addr: addr,
|
||||||
Handler: app.Handlers,
|
Handler: app.Handlers,
|
||||||
ReadTimeout: time.Duration(HttpServerTimeOut) * time.Second,
|
ReadTimeout: time.Duration(HttpServerTimeOut) * time.Second,
|
||||||
WriteTimeout: time.Duration(HttpServerTimeOut) * time.Second,
|
WriteTimeout: time.Duration(HttpServerTimeOut) * time.Second,
|
||||||
}
|
}
|
||||||
laddr, err := net.ResolveTCPAddr("tcp", addr)
|
if EnableHttpTLS {
|
||||||
if nil != err {
|
go func() {
|
||||||
BeeLogger.Critical("ResolveTCPAddr:", err)
|
if HttpsPort != 0 {
|
||||||
}
|
s.Addr = fmt.Sprintf("%s:%d", HttpAddr, HttpsPort)
|
||||||
l, err = GetInitListener(laddr)
|
|
||||||
if err == nil {
|
|
||||||
theStoppable = newStoppable(l)
|
|
||||||
err = server.Serve(theStoppable)
|
|
||||||
if err == nil {
|
|
||||||
theStoppable.wg.Wait()
|
|
||||||
err = CloseSelf()
|
|
||||||
}
|
}
|
||||||
}
|
err := s.ListenAndServeTLS(HttpCertFile, HttpKeyFile)
|
||||||
} else {
|
if err != nil {
|
||||||
s := &http.Server{
|
BeeLogger.Critical("ListenAndServeTLS: ", err)
|
||||||
Addr: addr,
|
time.Sleep(100 * time.Microsecond)
|
||||||
Handler: app.Handlers,
|
endRunning <- true
|
||||||
ReadTimeout: time.Duration(HttpServerTimeOut) * time.Second,
|
}
|
||||||
WriteTimeout: time.Duration(HttpServerTimeOut) * time.Second,
|
}()
|
||||||
}
|
}
|
||||||
if EnableHttpTLS {
|
|
||||||
go func() {
|
|
||||||
if HttpsPort != 0 {
|
|
||||||
s.Addr = fmt.Sprintf("%s:%d", HttpAddr, HttpsPort)
|
|
||||||
}
|
|
||||||
err := s.ListenAndServeTLS(HttpCertFile, HttpKeyFile)
|
|
||||||
if err != nil {
|
|
||||||
BeeLogger.Critical("ListenAndServeTLS: ", err)
|
|
||||||
time.Sleep(100 * time.Microsecond)
|
|
||||||
endRunning <- true
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
if EnableHttpListen {
|
if EnableHttpListen {
|
||||||
go func() {
|
go func() {
|
||||||
err := s.ListenAndServe()
|
err := s.ListenAndServe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
BeeLogger.Critical("ListenAndServe: ", err)
|
BeeLogger.Critical("ListenAndServe: ", err)
|
||||||
time.Sleep(100 * time.Microsecond)
|
time.Sleep(100 * time.Microsecond)
|
||||||
endRunning <- true
|
endRunning <- true
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +56,6 @@ var (
|
|||||||
MaxMemory int64
|
MaxMemory int64
|
||||||
EnableGzip bool // flag of enable gzip
|
EnableGzip bool // flag of enable gzip
|
||||||
DirectoryIndex bool // flag of display directory index. default is false.
|
DirectoryIndex bool // flag of display directory index. default is false.
|
||||||
EnableHotUpdate bool // flag of hot update checking by app self. default is false.
|
|
||||||
HttpServerTimeOut int64
|
HttpServerTimeOut int64
|
||||||
ErrorsShow bool // flag of show errors in page. if true, show error and trace info in page rendered with error template.
|
ErrorsShow bool // flag of show errors in page. if true, show error and trace info in page rendered with error template.
|
||||||
XSRFKEY string // xsrf hash salt string.
|
XSRFKEY string // xsrf hash salt string.
|
||||||
@ -101,6 +100,7 @@ func init() {
|
|||||||
|
|
||||||
// set this to 0.0.0.0 to make this app available to externally
|
// set this to 0.0.0.0 to make this app available to externally
|
||||||
EnableHttpListen = true //default enable http Listen
|
EnableHttpListen = true //default enable http Listen
|
||||||
|
|
||||||
HttpAddr = ""
|
HttpAddr = ""
|
||||||
HttpPort = 8080
|
HttpPort = 8080
|
||||||
|
|
||||||
@ -254,10 +254,6 @@ func ParseConfig() (err error) {
|
|||||||
DirectoryIndex = directoryindex
|
DirectoryIndex = directoryindex
|
||||||
}
|
}
|
||||||
|
|
||||||
if hotupdate, err := AppConfig.Bool("HotUpdate"); err == nil {
|
|
||||||
EnableHotUpdate = hotupdate
|
|
||||||
}
|
|
||||||
|
|
||||||
if timeout, err := AppConfig.Int64("HttpServerTimeOut"); err == nil {
|
if timeout, err := AppConfig.Int64("HttpServerTimeOut"); err == nil {
|
||||||
HttpServerTimeOut = timeout
|
HttpServerTimeOut = timeout
|
||||||
}
|
}
|
||||||
|
169
reload.go
169
reload.go
@ -1,169 +0,0 @@
|
|||||||
// Beego (http://beego.me/)
|
|
||||||
// @description beego is an open-source, high-performance web framework for the Go programming language.
|
|
||||||
// @link http://github.com/astaxie/beego for the canonical source repository
|
|
||||||
// @license http://github.com/astaxie/beego/blob/master/LICENSE
|
|
||||||
// @authors astaxie
|
|
||||||
|
|
||||||
package beego
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"os/signal"
|
|
||||||
"reflect"
|
|
||||||
"strconv"
|
|
||||||
"sync"
|
|
||||||
//"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// An environment variable when restarting application http listener.
|
|
||||||
FDKey = "BEEGO_HOT_FD"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Export an error equivalent to net.errClosing for use with Accept during
|
|
||||||
// a graceful exit.
|
|
||||||
var ErrClosing = errors.New("use of closed network connection")
|
|
||||||
var ErrInitStart = errors.New("init from")
|
|
||||||
|
|
||||||
// Allows for us to notice when the connection is closed.
|
|
||||||
type conn struct {
|
|
||||||
net.Conn
|
|
||||||
wg *sync.WaitGroup
|
|
||||||
isclose bool
|
|
||||||
lock *sync.Mutex
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close current processing connection.
|
|
||||||
func (c conn) Close() error {
|
|
||||||
c.lock.Lock()
|
|
||||||
defer c.lock.Unlock()
|
|
||||||
err := c.Conn.Close()
|
|
||||||
if !c.isclose && err == nil {
|
|
||||||
c.wg.Done()
|
|
||||||
c.isclose = true
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
type stoppableListener struct {
|
|
||||||
net.Listener
|
|
||||||
count int64
|
|
||||||
stopped bool
|
|
||||||
wg sync.WaitGroup
|
|
||||||
}
|
|
||||||
|
|
||||||
var theStoppable *stoppableListener
|
|
||||||
|
|
||||||
func newStoppable(l net.Listener) (sl *stoppableListener) {
|
|
||||||
sl = &stoppableListener{Listener: l}
|
|
||||||
|
|
||||||
// this goroutine monitors the channel. Can't do this in
|
|
||||||
// Accept (below) because once it enters sl.Listener.Accept()
|
|
||||||
// it blocks. We unblock it by closing the fd it is trying to
|
|
||||||
// accept(2) on.
|
|
||||||
go func() {
|
|
||||||
WaitSignal(l)
|
|
||||||
sl.stopped = true
|
|
||||||
sl.Listener.Close()
|
|
||||||
}()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set stopped Listener to accept requests again.
|
|
||||||
// it returns the accepted and closable connection or error.
|
|
||||||
func (sl *stoppableListener) Accept() (c net.Conn, err error) {
|
|
||||||
c, err = sl.Listener.Accept()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
sl.wg.Add(1)
|
|
||||||
// Wrap the returned connection, so that we can observe when
|
|
||||||
// it is closed.
|
|
||||||
c = conn{Conn: c, wg: &sl.wg}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listener waits signal to kill or interrupt then restart.
|
|
||||||
func WaitSignal(l net.Listener) error {
|
|
||||||
ch := make(chan os.Signal, 1)
|
|
||||||
signal.Notify(ch, os.Interrupt, os.Kill)
|
|
||||||
for {
|
|
||||||
sig := <-ch
|
|
||||||
log.Println(sig.String())
|
|
||||||
switch sig {
|
|
||||||
|
|
||||||
case os.Kill:
|
|
||||||
return nil
|
|
||||||
case os.Interrupt:
|
|
||||||
err := Restart(l)
|
|
||||||
if nil != err {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Kill current running os process.
|
|
||||||
func CloseSelf() error {
|
|
||||||
ppid := os.Getpid()
|
|
||||||
if ppid == 1 { // init provided sockets, for example systemd
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
p, err := os.FindProcess(ppid)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return p.Kill()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Re-exec this image without dropping the listener passed to this function.
|
|
||||||
func Restart(l net.Listener) error {
|
|
||||||
argv0, err := exec.LookPath(os.Args[0])
|
|
||||||
if nil != err {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
wd, err := os.Getwd()
|
|
||||||
if nil != err {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
v := reflect.ValueOf(l).Elem().FieldByName("fd").Elem()
|
|
||||||
fd := uintptr(v.FieldByName("sysfd").Int())
|
|
||||||
allFiles := append([]*os.File{os.Stdin, os.Stdout, os.Stderr},
|
|
||||||
os.NewFile(fd, string(v.FieldByName("sysfile").String())))
|
|
||||||
|
|
||||||
p, err := os.StartProcess(argv0, os.Args, &os.ProcAttr{
|
|
||||||
Dir: wd,
|
|
||||||
Env: append(os.Environ(), fmt.Sprintf("%s=%d", FDKey, fd)),
|
|
||||||
Files: allFiles,
|
|
||||||
})
|
|
||||||
if nil != err {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
log.Printf("spawned child %d\n", p.Pid)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get current net.Listen in running process.
|
|
||||||
func GetInitListener(tcpaddr *net.TCPAddr) (l net.Listener, err error) {
|
|
||||||
countStr := os.Getenv(FDKey)
|
|
||||||
if countStr == "" {
|
|
||||||
return net.ListenTCP("tcp", tcpaddr)
|
|
||||||
}
|
|
||||||
count, err := strconv.Atoi(countStr)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
f := os.NewFile(uintptr(count), "listen socket")
|
|
||||||
l, err = net.FileListener(f)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return l, nil
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user