Skip to content
Toggle navigation
Toggle navigation
This project
Loading...
Sign in
张磊
/
FileStorageBeego
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Issue Boards
Files
Commits
Network
Compare
Branches
Tags
45536776
authored
2013-06-07 17:48:04 +0800
by
astaxie
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
support hot-update
1 parent
be929036
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
171 additions
and
7 deletions
beego.go
reload.go
beego.go
View file @
4553677
...
...
@@ -29,10 +29,10 @@ var (
ViewsPath
string
RunMode
string
//"dev" or "prod"
AppConfig
*
Config
//related to session
//related to session
GlobalSessions
*
session
.
Manager
//GlobalSessions
SessionOn
bool
// wheather auto start session,default is false
SessionProvider
string
// default session provider memory mysql redis
SessionProvider
string
// default session provider memory mysql redis
SessionName
string
// sessionName cookie's name
SessionGCMaxLifetime
int64
// session's gc maxlifetime
SessionSavePath
string
// session savepath if use mysql/redis/file this set to the connectinfo
...
...
@@ -81,15 +81,27 @@ func NewApp() *App {
func
(
app
*
App
)
Run
()
{
addr
:=
fmt
.
Sprintf
(
"%s:%d"
,
HttpAddr
,
HttpPort
)
var
err
error
var
(
err
error
l
net
.
Listener
)
if
UseFcgi
{
l
,
e
:
=
net
.
Listen
(
"tcp"
,
addr
)
if
e
!=
nil
{
BeeLogger
.
Fatal
(
"Listen: "
,
e
)
l
,
e
rr
=
net
.
Listen
(
"tcp"
,
addr
)
if
e
rr
!=
nil
{
BeeLogger
.
Fatal
(
"Listen: "
,
e
rr
)
}
err
=
fcgi
.
Serve
(
l
,
app
.
Handlers
)
}
else
{
err
=
http
.
ListenAndServe
(
addr
,
app
.
Handlers
)
server
:=
&
http
.
Server
{
Handler
:
app
.
Handlers
}
laddr
,
err
:=
net
.
ResolveTCPAddr
(
"tcp"
,
addr
)
if
nil
!=
err
{
BeeLogger
.
Fatal
(
"ResolveTCPAddr:"
,
err
)
}
l
,
err
=
GetInitListner
(
laddr
)
theStoppable
=
newStoppable
(
l
)
err
=
server
.
Serve
(
theStoppable
)
theStoppable
.
wg
.
Wait
()
CloseSelf
()
}
if
err
!=
nil
{
BeeLogger
.
Fatal
(
"ListenAndServe: "
,
err
)
...
...
reload.go
0 → 100644
View file @
4553677
// Zero-downtime restarts in Go.
package
beego
import
(
"errors"
"fmt"
"log"
"net"
"os"
"os/exec"
"os/signal"
"reflect"
"strconv"
"sync"
"syscall"
)
const
(
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
}
func
(
c
conn
)
Close
()
error
{
err
:=
c
.
Conn
.
Close
()
c
.
wg
.
Done
()
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
}
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
}
func
WaitSignal
(
l
net
.
Listener
)
error
{
ch
:=
make
(
chan
os
.
Signal
,
1
)
signal
.
Notify
(
ch
,
syscall
.
SIGTERM
,
syscall
.
SIGHUP
)
for
{
sig
:=
<-
ch
log
.
Println
(
sig
.
String
())
switch
sig
{
case
syscall
.
SIGTERM
:
return
nil
case
syscall
.
SIGHUP
:
err
:=
Restart
(
l
)
if
nil
!=
err
{
return
err
}
return
nil
}
}
return
nil
// It'll never get here.
}
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
}
func
GetInitListner
(
tcpaddr
*
net
.
TCPAddr
)
(
l
net
.
Listener
,
err
error
)
{
countStr
:=
os
.
Getenv
(
FDKey
)
if
countStr
==
""
{
return
net
.
ListenTCP
(
"tcp"
,
tcpaddr
)
}
else
{
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
}
}
Write
Preview
Styling with
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment