mirror of
https://github.com/jech/galene.git
synced 2024-11-22 16:45:58 +01:00
Implement graceful server shutdown.
This gives the user a friendly message when the server shuts down.
This commit is contained in:
parent
7707775cca
commit
e37e27036e
5 changed files with 41 additions and 7 deletions
|
@ -12,3 +12,7 @@ type client interface {
|
||||||
pushConn(id string, conn upConnection, tracks []upTrack, label string) error
|
pushConn(id string, conn upConnection, tracks []upTrack, label string) error
|
||||||
pushClient(id, username string, add bool) error
|
pushClient(id, username string, add bool) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type kickable interface {
|
||||||
|
kick(message string) error
|
||||||
|
}
|
||||||
|
|
12
group.go
12
group.go
|
@ -64,7 +64,7 @@ type connectionFailedAction struct {
|
||||||
|
|
||||||
type permissionsChangedAction struct{}
|
type permissionsChangedAction struct{}
|
||||||
|
|
||||||
type kickAction struct{
|
type kickAction struct {
|
||||||
message string
|
message string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,6 +288,16 @@ func (g *group) Range(f func(c client) bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *group) shutdown(message string) {
|
||||||
|
g.Range(func(c client) bool {
|
||||||
|
cc, ok := c.(kickable)
|
||||||
|
if ok {
|
||||||
|
cc.kick(message)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const maxChatHistory = 20
|
const maxChatHistory = 20
|
||||||
|
|
||||||
func (g *group) clearChatHistory() {
|
func (g *group) clearChatHistory() {
|
||||||
|
|
3
sfu.go
3
sfu.go
|
@ -87,6 +87,7 @@ func main() {
|
||||||
webserver()
|
webserver()
|
||||||
|
|
||||||
terminate := make(chan os.Signal, 1)
|
terminate := make(chan os.Signal, 1)
|
||||||
signal.Notify(terminate, syscall.SIGINT)
|
signal.Notify(terminate, syscall.SIGINT, syscall.SIGTERM)
|
||||||
<-terminate
|
<-terminate
|
||||||
|
shutdown()
|
||||||
}
|
}
|
||||||
|
|
10
webclient.go
10
webclient.go
|
@ -943,6 +943,10 @@ func setPermissions(g *group, id string, perm string) error {
|
||||||
return c.action(permissionsChangedAction{})
|
return c.action(permissionsChangedAction{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *webClient) kick(message string) error {
|
||||||
|
return c.action(kickAction{message})
|
||||||
|
}
|
||||||
|
|
||||||
func kickClient(g *group, id string, message string) error {
|
func kickClient(g *group, id string, message string) error {
|
||||||
g.mu.Lock()
|
g.mu.Lock()
|
||||||
defer g.mu.Unlock()
|
defer g.mu.Unlock()
|
||||||
|
@ -952,12 +956,12 @@ func kickClient(g *group, id string, message string) error {
|
||||||
return userError("no such user")
|
return userError("no such user")
|
||||||
}
|
}
|
||||||
|
|
||||||
c, ok := client.(*webClient)
|
c, ok := client.(kickable)
|
||||||
if !ok {
|
if !ok {
|
||||||
return userError("this is not a real user")
|
return userError("this client is not kickable")
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.action(kickAction{message})
|
return c.kick(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleClientMessage(c *webClient, m clientMessage) error {
|
func handleClientMessage(c *webClient, m clientMessage) error {
|
||||||
|
|
19
webserver.go
19
webserver.go
|
@ -2,6 +2,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -19,6 +20,8 @@ import (
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var server *http.Server
|
||||||
|
|
||||||
func webserver() {
|
func webserver() {
|
||||||
http.Handle("/", mungeHandler{http.FileServer(http.Dir(staticRoot))})
|
http.Handle("/", mungeHandler{http.FileServer(http.Dir(staticRoot))})
|
||||||
http.HandleFunc("/group/", groupHandler)
|
http.HandleFunc("/group/", groupHandler)
|
||||||
|
@ -39,17 +42,24 @@ func webserver() {
|
||||||
http.HandleFunc("/stats", statsHandler)
|
http.HandleFunc("/stats", statsHandler)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
server := &http.Server{
|
server = &http.Server{
|
||||||
Addr: httpAddr,
|
Addr: httpAddr,
|
||||||
ReadHeaderTimeout: 60 * time.Second,
|
ReadHeaderTimeout: 60 * time.Second,
|
||||||
IdleTimeout: 120 * time.Second,
|
IdleTimeout: 120 * time.Second,
|
||||||
}
|
}
|
||||||
|
server.RegisterOnShutdown(func() {
|
||||||
|
groups.mu.Lock()
|
||||||
|
defer groups.mu.Unlock()
|
||||||
|
for _, g := range groups.groups {
|
||||||
|
go g.shutdown("server is shutting down")
|
||||||
|
}
|
||||||
|
})
|
||||||
var err error
|
var err error
|
||||||
err = server.ListenAndServeTLS(
|
err = server.ListenAndServeTLS(
|
||||||
filepath.Join(dataDir, "cert.pem"),
|
filepath.Join(dataDir, "cert.pem"),
|
||||||
filepath.Join(dataDir, "key.pem"),
|
filepath.Join(dataDir, "key.pem"),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil && err != http.ErrServerClosed {
|
||||||
log.Printf("ListenAndServeTLS: %v", err)
|
log.Printf("ListenAndServeTLS: %v", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
@ -457,3 +467,8 @@ func serveGroupRecordings(w http.ResponseWriter, r *http.Request, f *os.File, gr
|
||||||
fmt.Fprintf(w, "</table>\n")
|
fmt.Fprintf(w, "</table>\n")
|
||||||
fmt.Fprintf(w, "</body></html>\n")
|
fmt.Fprintf(w, "</body></html>\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func shutdown() {
|
||||||
|
ctx, _ := context.WithTimeout(context.Background(), 2*time.Second)
|
||||||
|
server.Shutdown(ctx)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue