mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-08-02 16:08:31 +00:00
Better shutdown code, release listeners
This commit is contained in:
parent
b108177942
commit
44249a3721
3 changed files with 73 additions and 33 deletions
|
@ -1,6 +1,7 @@
|
||||||
package main // import "github.com/FrankerFaceZ/FrankerFaceZ/socketserver/cmd/ffzsocketserver"
|
package main // import "github.com/FrankerFaceZ/FrankerFaceZ/socketserver/cmd/ffzsocketserver"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -8,6 +9,10 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"sync"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/FrankerFaceZ/FrankerFaceZ/socketserver/server"
|
"github.com/FrankerFaceZ/FrankerFaceZ/socketserver/server"
|
||||||
)
|
)
|
||||||
|
@ -56,17 +61,63 @@ func main() {
|
||||||
|
|
||||||
go commandLineConsole()
|
go commandLineConsole()
|
||||||
|
|
||||||
|
var server1, server2 *http.Server
|
||||||
|
|
||||||
|
stopSig := make(chan os.Signal, 3)
|
||||||
|
signal.Notify(stopSig, os.Interrupt)
|
||||||
|
signal.Notify(stopSig, syscall.SIGUSR1)
|
||||||
|
signal.Notify(stopSig, syscall.SIGTERM)
|
||||||
|
|
||||||
if conf.UseSSL {
|
if conf.UseSSL {
|
||||||
|
server1 = &http.Server{
|
||||||
|
Addr: conf.SSLListenAddr,
|
||||||
|
Handler: http.DefaultServeMux,
|
||||||
|
}
|
||||||
go func() {
|
go func() {
|
||||||
if err := http.ListenAndServeTLS(conf.SSLListenAddr, conf.SSLCertificateFile, conf.SSLKeyFile, http.DefaultServeMux); err != nil {
|
if err := server1.ListenAndServeTLS(conf.SSLCertificateFile, conf.SSLKeyFile); err != nil {
|
||||||
log.Fatal("ListenAndServeTLS: ", err)
|
log.Println("ListenAndServeTLS:", err)
|
||||||
|
stopSig <- os.Interrupt
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = http.ListenAndServe(conf.ListenAddr, http.DefaultServeMux); err != nil {
|
if true {
|
||||||
log.Fatal("ListenAndServe: ", err)
|
server2 = &http.Server{
|
||||||
|
Addr: conf.ListenAddr,
|
||||||
|
Handler: http.DefaultServeMux,
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
if err := server2.ListenAndServe(); err != nil {
|
||||||
|
log.Println("ListenAndServe: ", err)
|
||||||
|
stopSig <- os.Interrupt
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<-stopSig
|
||||||
|
log.Println("Shutting down...")
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
if conf.UseSSL {
|
||||||
|
server1.Shutdown(ctx)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
server2.Shutdown(ctx)
|
||||||
|
}()
|
||||||
|
server.Shutdown(&wg)
|
||||||
|
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateKeys(outputFile string) {
|
func generateKeys(outputFile string) {
|
||||||
|
|
|
@ -141,9 +141,11 @@ func (backend *backendInfo) SendRemoteCommand(remoteCommand, data string, auth A
|
||||||
return "", ErrAuthorizationNeeded
|
return "", ErrAuthorizationNeeded
|
||||||
} else if resp.StatusCode < 200 || resp.StatusCode > 299 { // any non-2xx
|
} else if resp.StatusCode < 200 || resp.StatusCode > 299 { // any non-2xx
|
||||||
// If the Content-Type header includes a charset, ignore it.
|
// If the Content-Type header includes a charset, ignore it.
|
||||||
|
// typeStr, _, _ = mime.ParseMediaType(resp.Header.Get("Content-Type"))
|
||||||
|
// inline the part of the function we care about
|
||||||
typeStr := resp.Header.Get("Content-Type")
|
typeStr := resp.Header.Get("Content-Type")
|
||||||
splitIdx := strings.IndexRune(typeStr, ';')
|
splitIdx := strings.IndexRune(typeStr, ';')
|
||||||
if ( splitIdx != -1 ) {
|
if splitIdx != -1 {
|
||||||
typeStr = strings.TrimSpace(typeStr[0:splitIdx])
|
typeStr = strings.TrimSpace(typeStr[0:splitIdx])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -139,30 +139,21 @@ func startJanitors() {
|
||||||
go pubsubJanitor()
|
go pubsubJanitor()
|
||||||
|
|
||||||
go ircConnection()
|
go ircConnection()
|
||||||
go shutdownHandler()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// is_init_func
|
// Shutdown disconnects all clients.
|
||||||
func shutdownHandler() {
|
func Shutdown(wg *sync.WaitGroup) {
|
||||||
ch := make(chan os.Signal)
|
|
||||||
signal.Notify(ch, syscall.SIGUSR1)
|
|
||||||
signal.Notify(ch, syscall.SIGTERM)
|
|
||||||
<-ch
|
|
||||||
log.Println("Shutting down...")
|
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
writeHLL()
|
writeHLL()
|
||||||
wg.Done()
|
|
||||||
}()
|
}()
|
||||||
|
wg.Add(1)
|
||||||
StopAcceptingConnections = true
|
go func() {
|
||||||
close(StopAcceptingConnectionsCh)
|
defer wg.Done()
|
||||||
|
close(StopAcceptingConnectionsCh)
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
wg.Wait()
|
}()
|
||||||
os.Exit(0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// is_init_func +test
|
// is_init_func +test
|
||||||
|
@ -200,7 +191,6 @@ var BannerHTML []byte
|
||||||
|
|
||||||
// StopAcceptingConnectionsCh is closed while the server is shutting down.
|
// StopAcceptingConnectionsCh is closed while the server is shutting down.
|
||||||
var StopAcceptingConnectionsCh = make(chan struct{})
|
var StopAcceptingConnectionsCh = make(chan struct{})
|
||||||
var StopAcceptingConnections = false
|
|
||||||
|
|
||||||
// HTTPHandleRootURL is the http.HandleFunc for requests on `/`.
|
// HTTPHandleRootURL is the http.HandleFunc for requests on `/`.
|
||||||
// It either uses the SocketUpgrader or writes out the BannerHTML.
|
// It either uses the SocketUpgrader or writes out the BannerHTML.
|
||||||
|
@ -211,13 +201,6 @@ func HTTPHandleRootURL(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// racy, but should be ok?
|
|
||||||
if StopAcceptingConnections {
|
|
||||||
w.WriteHeader(503)
|
|
||||||
fmt.Fprint(w, "server is shutting down")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if strings.Contains(strings.ToLower(r.Header.Get("Connection")), "upgrade") {
|
if strings.Contains(strings.ToLower(r.Header.Get("Connection")), "upgrade") {
|
||||||
updateSysMem()
|
updateSysMem()
|
||||||
|
|
||||||
|
@ -376,8 +359,10 @@ func RunSocketConnection(conn *websocket.Conn) {
|
||||||
|
|
||||||
// And done.
|
// And done.
|
||||||
|
|
||||||
if !StopAcceptingConnections {
|
select {
|
||||||
|
case <-StopAcceptingConnectionsCh:
|
||||||
// Don't perform high contention operations when server is closing
|
// Don't perform high contention operations when server is closing
|
||||||
|
default:
|
||||||
atomic.AddUint64(&Statistics.CurrentClientCount, NegativeOne)
|
atomic.AddUint64(&Statistics.CurrentClientCount, NegativeOne)
|
||||||
atomic.AddUint64(&Statistics.ClientDisconnectsTotal, 1)
|
atomic.AddUint64(&Statistics.ClientDisconnectsTotal, 1)
|
||||||
|
|
||||||
|
@ -410,7 +395,9 @@ func runSocketReader(conn *websocket.Conn, client *ClientInfo, errorChan chan<-
|
||||||
|
|
||||||
msg = ClientMessage{}
|
msg = ClientMessage{}
|
||||||
msgErr := UnmarshalClientMessage(packet, messageType, &msg)
|
msgErr := UnmarshalClientMessage(packet, messageType, &msg)
|
||||||
if _, ok := msgErr.(interface{IsFatal() bool}); ok {
|
if _, ok := msgErr.(interface {
|
||||||
|
IsFatal() bool
|
||||||
|
}); ok {
|
||||||
errorChan <- msgErr
|
errorChan <- msgErr
|
||||||
continue
|
continue
|
||||||
} else if msgErr != nil {
|
} else if msgErr != nil {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue