Albirew/nyaa-pantsu
Albirew
/
nyaa-pantsu
Archivé
1
0
Bifurcation 0

Let net/http gracefully close

http.Server.Shutdown gracefully closes listeners/clients, we do not have to
do it ourselves. Making util/signals accept func() instead of io.Closer
allowed for the removal of network/closer.go and util/signals/closers.go.
Cette révision appartient à :
John Smith 2017-05-29 08:15:21 +02:00 révisé par Eliot Whalan
Parent 0159579611
révision 0bdd915f9a
Signature inconnue de Forgejo
ID de la clé GPG: C0A42175139840D6
4 fichiers modifiés avec 44 ajouts et 62 suppressions

42
main.go
Voir le fichier

@ -4,6 +4,7 @@ import (
"bufio"
"flag"
"context"
"net/http"
"os"
"time"
@ -37,19 +38,24 @@ func RunServer(conf *config.Config) {
}
l, err := network.CreateHTTPListener(conf)
log.CheckError(err)
if err == nil {
// add http server to be closed gracefully
signals.RegisterCloser(&network.GracefulHttpCloser{
Server: srv,
Listener: l,
})
log.Infof("listening on %s", l.Addr())
err := srv.Serve(l)
if err != nil && err != network.ErrListenerStopped {
log.CheckError(err)
}
if err != nil {
return
}
log.Infof("listening on %s", l.Addr())
// http.Server.Shutdown closes associated listeners/clients.
// context.Background causes srv to indefinitely try to
// gracefully shutdown. add a timeout if this becomes a problem.
signals.OnInterrupt(func() {
srv.Shutdown(context.Background())
})
err = srv.Serve(l)
if err == nil {
log.Panic("http.Server.Serve never returns nil")
}
if err == http.ErrServerClosed {
return
}
log.CheckError(err)
}
// RunScraper runs tracker scraper mainloop
@ -73,10 +79,10 @@ func RunScraper(conf *config.Config) {
workers = 1
}
// register udp socket with signals
signals.RegisterCloser(pc)
// register scraper with signals
signals.RegisterCloser(scraper)
signals.OnInterrupt(func() {
pc.Close()
scraper.Close()
})
// run udp scraper worker
for workers > 0 {
log.Infof("starting up worker %d", workers)
@ -96,7 +102,9 @@ func RunMetainfoFetcher(conf *config.Config) {
return
}
signals.RegisterCloser(fetcher)
signals.OnInterrupt(func() {
fetcher.Close()
})
fetcher.RunAsync()
fetcher.Wait()
}

Voir le fichier

@ -1,18 +0,0 @@
package network
import (
"net"
"net/http"
)
// GracefulHttpCloser : implements io.Closer that gracefully closes an http server
type GracefulHttpCloser struct {
Server *http.Server
Listener net.Listener
}
// Close method
func (c *GracefulHttpCloser) Close() error {
c.Listener.Close()
return c.Server.Shutdown(nil)
}

Voir le fichier

@ -1,26 +0,0 @@
package signals
import (
"io"
"sync"
)
var (
closeAccess sync.Mutex
closers []io.Closer
)
// RegisterCloser adds an io.Closer to close on interrupt
func RegisterCloser(c io.Closer) {
closeAccess.Lock()
closers = append(closers, c)
closeAccess.Unlock()
}
func closeClosers() {
closeAccess.Lock()
for _, c := range closers {
c.Close()
}
closeAccess.Unlock()
}

Voir le fichier

@ -3,8 +3,22 @@ package signals
import (
"github.com/NyaaPantsu/nyaa/router"
"github.com/NyaaPantsu/nyaa/util/log"
"sync"
)
// registered interrupt callbacks.
// currently only used to gracefully close the server.
var intEvents struct {
lock sync.Mutex
funcs []func()
}
func OnInterrupt(fn func()) {
intEvents.lock.Lock()
intEvents.funcs = append(intEvents.funcs, fn)
intEvents.lock.Unlock()
}
func handleReload() {
log.Info("Got SIGHUP")
router.ReloadTemplates()
@ -13,5 +27,9 @@ func handleReload() {
// handle interrupt signal, platform independent
func interrupted() {
closeClosers()
intEvents.lock.Lock()
for _, fn := range intEvents.funcs {
fn()
}
intEvents.lock.Unlock()
}