network/graceful.go made redundant
The call to http.Server.Shutdown in main.go that happens on os.Interrupt closes listeners. Remove racey code and format network/network.go. Running Listener.Accept in a loop is not necessary as the stdlib expects SA_RESTART to be set for signal handlers.
Cette révision appartient à :
Parent
7cb69b5234
révision
d2edca62de
2 fichiers modifiés avec 13 ajouts et 80 suppressions
|
@ -1,61 +0,0 @@
|
|||
package network
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
)
|
||||
|
||||
var ErrListenerStopped = errors.New("listener was stopped")
|
||||
|
||||
// GracefulListener provides safe and graceful net.Listener wrapper that prevents error on graceful shutdown
|
||||
type GracefulListener struct {
|
||||
listener net.Listener
|
||||
stop chan int
|
||||
}
|
||||
|
||||
// Accept method
|
||||
func (l *GracefulListener) Accept() (net.Conn, error) {
|
||||
for {
|
||||
c, err := l.listener.Accept()
|
||||
select {
|
||||
case <-l.stop:
|
||||
if c != nil {
|
||||
c.Close()
|
||||
}
|
||||
close(l.stop)
|
||||
l.stop = nil
|
||||
return nil, ErrListenerStopped
|
||||
default:
|
||||
|
||||
}
|
||||
if err != nil {
|
||||
neterr, ok := err.(net.Error)
|
||||
if ok && neterr.Timeout() && neterr.Temporary() {
|
||||
continue
|
||||
}
|
||||
}
|
||||
return c, err
|
||||
}
|
||||
}
|
||||
|
||||
// Close method
|
||||
func (l *GracefulListener) Close() (err error) {
|
||||
l.listener.Close()
|
||||
if l.stop != nil {
|
||||
l.stop <- 0
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Addr method
|
||||
func (l *GracefulListener) Addr() net.Addr {
|
||||
return l.listener.Addr()
|
||||
}
|
||||
|
||||
// WrapListener wraps a net.Listener such that it can be closed gracefully
|
||||
func WrapListener(l net.Listener) net.Listener {
|
||||
return &GracefulListener{
|
||||
listener: l,
|
||||
stop: make(chan int),
|
||||
}
|
||||
}
|
|
@ -9,33 +9,27 @@ import (
|
|||
)
|
||||
|
||||
// CreateHTTPListener creates a net.Listener for main http webapp given main config
|
||||
func CreateHTTPListener(conf *config.Config) (l net.Listener, err error) {
|
||||
if conf.I2P == nil {
|
||||
l, err = net.Listen("tcp", fmt.Sprintf("%s:%d", conf.Host, conf.Port))
|
||||
} else {
|
||||
func CreateHTTPListener(conf *config.Config) (net.Listener, error) {
|
||||
if conf.I2P != nil {
|
||||
s := i2p.NewSession(conf.I2P.Name, conf.I2P.Addr, conf.I2P.Keyfile)
|
||||
err = s.Open()
|
||||
err := s.Open()
|
||||
if s != nil {
|
||||
log.Infof("i2p address: %s", s.B32Addr())
|
||||
l = s
|
||||
}
|
||||
return s, err
|
||||
}
|
||||
if l != nil {
|
||||
l = WrapListener(l)
|
||||
}
|
||||
return
|
||||
return net.Listen("tcp", fmt.Sprintf("%s:%d", conf.Host, conf.Port))
|
||||
}
|
||||
|
||||
// CreateScraperSocket creates a UDP Scraper socket
|
||||
func CreateScraperSocket(conf *config.Config) (pc net.PacketConn, err error) {
|
||||
if conf.I2P == nil {
|
||||
var laddr *net.UDPAddr
|
||||
laddr, err = net.ResolveUDPAddr("udp", conf.Scrape.Addr)
|
||||
if err == nil {
|
||||
pc, err = net.ListenUDP("udp", laddr)
|
||||
}
|
||||
} else {
|
||||
func CreateScraperSocket(conf *config.Config) (net.PacketConn, error) {
|
||||
if conf.I2P != nil {
|
||||
log.Fatal("i2p udp scraper not supported")
|
||||
}
|
||||
return
|
||||
var laddr *net.UDPAddr
|
||||
laddr, err := net.ResolveUDPAddr("udp", conf.Scrape.Addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return net.ListenUDP("udp", laddr)
|
||||
}
|
||||
|
|
Référencer dans un nouveau ticket