@@ -3,6 +3,7 @@ package revel
3
3
import (
4
4
"code.google.com/p/go.net/websocket"
5
5
"fmt"
6
+ "github.com/rcrowley/goagain"
6
7
"io"
7
8
"net"
8
9
"net/http"
@@ -110,14 +111,46 @@ func Run(port int) {
110
111
// to terminate SSL upstream when using unix domain sockets.
111
112
ERROR .Fatalln ("SSL is only supported for TCP sockets. Specify a port to listen on." )
112
113
}
113
- ERROR .Fatalln ("Failed to listen:" ,
114
- Server .ListenAndServeTLS (HttpSslCert , HttpSslKey ))
114
+ ERROR .Fatalln ("Failed to listen:" , Server .ListenAndServeTLS (HttpSslCert , HttpSslKey ))
115
+ } else if Config .BoolDefault ("graceful" , false ) {
116
+ serveGraceful (network , localAddress )
115
117
} else {
116
- listener , err := net .Listen (network , localAddress )
117
- if err != nil {
118
- ERROR .Fatalln ("Failed to listen:" , err )
118
+ ERROR .Fatalln ("Failed to serve:" , Server .Serve (listen (network , localAddress )))
119
+ }
120
+ }
121
+
122
+ func listen (network , localAddress string ) net.Listener {
123
+ listener , err := net .Listen (network , localAddress )
124
+ if err != nil {
125
+ ERROR .Fatalln ("Failed to listen:" , err )
126
+ }
127
+ return listener
128
+ }
129
+
130
+ func serveGraceful (network , localAddress string ) {
131
+ listener , err := goagain .Listener ()
132
+
133
+ if err != nil {
134
+ // New process, create the listener.
135
+ listener = listen (network , localAddress )
136
+ go Server .Serve (listener )
137
+ } else {
138
+ // Forked child, recover the listener.
139
+ INFO .Println ("Resuming listening on" , listener .Addr ())
140
+ go Server .Serve (listener )
141
+
142
+ // Child is ready to accept connections, kill parent process.
143
+ if err := goagain .Kill (); err != nil {
144
+ ERROR .Println ("Failed to kill parent:" , err )
119
145
}
120
- ERROR .Fatalln ("Failed to serve:" , Server .Serve (listener ))
146
+ }
147
+
148
+ if _ , err := goagain .Wait (listener ); err != nil {
149
+ ERROR .Fatalln ("Failed to serve:" , err )
150
+ }
151
+
152
+ if err := listener .Close (); err != nil {
153
+ ERROR .Fatalln ("Failed to close listener:" , err )
121
154
}
122
155
}
123
156
0 commit comments