add signal handling boilerblate

This commit is contained in:
Jeff Becker
2017-08-27 10:48:34 -04:00
parent 0765c8b302
commit aeb33c27aa
7 changed files with 150 additions and 4 deletions

1
.gitignore vendored
View File

@ -5,3 +5,4 @@
*.coverprofile
*exportable-fuzz.zip
go-i2p
*.exe

View File

@ -1,14 +1,17 @@
package router
import (
log "github.com/Sirupsen/logrus"
"github.com/hkparker/go-i2p/lib/config"
"github.com/hkparker/go-i2p/lib/netdb"
"time"
)
// i2p router type
type Router struct {
cfg *config.RouterConfig
ndb netdb.StdNetDB
cfg *config.RouterConfig
ndb netdb.StdNetDB
closeChnl chan bool
}
// create router with default configuration
@ -22,9 +25,22 @@ func CreateRouter() (r *Router, err error) {
func FromConfig(c *config.RouterConfig) (r *Router, err error) {
r = new(Router)
r.cfg = c
r.closeChnl = make(chan bool)
return
}
func (r *Router) Wait() {
<-r.closeChnl
}
func (r *Router) Stop() {
r.closeChnl <- true
}
func (r *Router) Close() error {
return nil
}
// run i2p router mainloop
func (r *Router) Run() {
r.ndb = netdb.StdNetDB(r.cfg.NetDb.Path)
@ -32,5 +48,17 @@ func (r *Router) Run() {
err := r.ndb.Ensure()
if err == nil {
// netdb ready
log.WithFields(log.Fields{
"at": "(Router) Run",
}).Info("Router ready")
for err == nil {
time.Sleep(time.Second)
}
} else {
// netdb failed
log.WithFields(log.Fields{
"at": "(Router) Run",
"reason": err.Error(),
}).Error("Netdb Startup failed")
}
}

16
lib/util/closeables.go Normal file
View File

@ -0,0 +1,16 @@
package util
import "io"
var closeOnExit []io.Closer
func RegisterCloser(c io.Closer) {
closeOnExit = append(closeOnExit, c)
}
func CloseAll() {
for idx := range closeOnExit {
closeOnExit[idx].Close()
}
closeOnExit = nil
}

View File

@ -0,0 +1,33 @@
package signals
import (
"os"
)
var sigChan = make(chan os.Signal)
type Handler func()
var reloaders []Handler
func RegisterReloadHandler(f Handler) {
reloaders = append(reloaders, f)
}
func handleReload() {
for idx := range reloaders {
reloaders[idx]()
}
}
var interrupters []Handler
func RegisterInterruptHandler(f Handler) {
interrupters = append(interrupters, f)
}
func handleInterrupted() {
for idx := range interrupters {
interrupters[idx]()
}
}

30
lib/util/signals/unix.go Normal file
View File

@ -0,0 +1,30 @@
// +build !windows
package signals
import (
"os/signal"
"syscall"
)
func init() {
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)
}
func Handle() {
for {
sig, ok := <-sigChan
if !ok {
// closed channel
return
}
if sig == syscall.SIGHUP {
handleReload()
} else if sig == syscall.SIGINT || sig == syscall.SIGTERM {
handleInterrupted()
} else {
// wtf?
}
}
}

View File

@ -0,0 +1,28 @@
// +build windows
package signals
import (
"os"
"os/signal"
)
func init() {
signal.Notify(sigChan, os.Interrupt)
}
func Handle() {
for {
sig, ok := <-sigChan
if !ok {
// closed channel
return
}
if sig == os.Interrupt {
handleInterrupted()
} else {
// wtf?
}
}
}

14
main.go
View File

@ -3,16 +3,26 @@ package main
import (
log "github.com/Sirupsen/logrus"
"github.com/hkparker/go-i2p/lib/router"
"github.com/hkparker/go-i2p/lib/util/signals"
)
func main() {
go signals.Handle()
log.Info("parsing i2p router configuration")
log.Info("starting up i2p router")
r, err := router.CreateRouter()
if err == nil {
r.Run()
signals.RegisterReloadHandler(func() {
// TODO: reload config
})
signals.RegisterInterruptHandler(func() {
// TODO: graceful shutdown
r.Stop()
})
go r.Run()
defer r.Close()
r.Wait()
} else {
log.Errorf("failed to create i2p router: %s", err)
}