add signal handling boilerblate
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,3 +5,4 @@
|
||||
*.coverprofile
|
||||
*exportable-fuzz.zip
|
||||
go-i2p
|
||||
*.exe
|
@ -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
16
lib/util/closeables.go
Normal 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
|
||||
}
|
33
lib/util/signals/signals.go
Normal file
33
lib/util/signals/signals.go
Normal 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
30
lib/util/signals/unix.go
Normal 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?
|
||||
}
|
||||
}
|
||||
|
||||
}
|
28
lib/util/signals/windows.go
Normal file
28
lib/util/signals/windows.go
Normal 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
14
main.go
@ -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)
|
||||
}
|
||||
|
Reference in New Issue
Block a user