Add reload support

(cherry picked from commit e98000c371)
This commit is contained in:
yaotthaha 2023-10-10 10:40:10 +08:00 committed by CHIZI-0618
parent 186c17abe5
commit a189daaa66
7 changed files with 76 additions and 4 deletions

View File

@ -71,6 +71,8 @@ type Router interface {
SetV2RayServer(server V2RayServer)
ResetNetwork() error
Reload()
}
func ContextWithRouter(ctx context.Context, router Router) context.Context {

8
box.go
View File

@ -40,6 +40,7 @@ type Box struct {
preServices1 map[string]adapter.Service
preServices2 map[string]adapter.Service
postServices map[string]adapter.Service
reloadChan chan struct{}
done chan struct{}
}
@ -52,6 +53,7 @@ type Options struct {
func New(options Options) (*Box, error) {
createdAt := time.Now()
reloadChan := make(chan struct{}, 1)
ctx := options.Context
if ctx == nil {
ctx = context.Background()
@ -95,6 +97,7 @@ func New(options Options) (*Box, error) {
common.PtrValueOrDefault(options.NTP),
options.Inbounds,
options.PlatformInterface,
reloadChan,
)
if err != nil {
return nil, E.Cause(err, "parse route options")
@ -218,6 +221,7 @@ func New(options Options) (*Box, error) {
preServices1: preServices1,
preServices2: preServices2,
postServices: postServices,
reloadChan: reloadChan,
done: make(chan struct{}),
}, nil
}
@ -462,3 +466,7 @@ func (s *Box) Close() error {
func (s *Box) Router() adapter.Router {
return s.router
}
func (s *Box) ReloadChan() <-chan struct{} {
return s.reloadChan
}

View File

@ -177,20 +177,31 @@ func run() error {
}
runtimeDebug.FreeOSMemory()
for {
osSignal := <-osSignals
if osSignal == syscall.SIGHUP {
reloadTag := false
select {
case osSignal := <-osSignals:
if osSignal == syscall.SIGHUP {
err = check()
if err != nil {
log.Error(E.Cause(err, "reload service"))
continue
}
reloadTag = true
}
case <-instance.ReloadChan():
err = check()
if err != nil {
log.Error(E.Cause(err, "reload service"))
continue
}
reloadTag = true
}
cancel()
closeCtx, closed := context.WithCancel(context.Background())
go closeMonitor(closeCtx)
err = instance.Close()
closed()
if osSignal != syscall.SIGHUP {
if !reloadTag {
if err != nil {
log.Error(E.Cause(err, "sing-box did not closed properly"))
}

View File

@ -12,7 +12,8 @@ import (
func configRouter(server *Server, logFactory log.Factory) http.Handler {
r := chi.NewRouter()
r.Get("/", getConfigs(server, logFactory))
r.Put("/", updateConfigs)
// r.Put("/", updateConfigs)
r.Put("/", reload(server))
r.Patch("/", patchConfigs(server))
return r
}

View File

@ -0,0 +1,19 @@
//go:build !ios
package clashapi
import (
"net/http"
"github.com/go-chi/render"
)
func reload(server *Server) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
defer func() {
server.logger.Warn("sing-box restarting...")
server.router.Reload()
}()
render.NoContent(w, r)
}
}

View File

@ -0,0 +1,19 @@
//go:build ios
package clashapi
import (
"net/http"
"github.com/go-chi/render"
)
var ErrOSNotSupported = &HTTPError{
Message: "OS not supported",
}
func reload(server *Server) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
render.JSON(w, r, ErrOSNotSupported)
}
}

View File

@ -100,6 +100,7 @@ type Router struct {
needPackageManager bool
wifiState adapter.WIFIState
started bool
reloadChan chan<- struct{}
}
func NewRouter(
@ -110,6 +111,7 @@ func NewRouter(
ntpOptions option.NTPOptions,
inbounds []option.Inbound,
platformInterface platform.Interface,
reloadChan chan<- struct{},
) (*Router, error) {
router := &Router{
ctx: ctx,
@ -138,6 +140,7 @@ func NewRouter(
needPackageManager: common.Any(inbounds, func(inbound option.Inbound) bool {
return len(inbound.TunOptions.IncludePackage) > 0 || len(inbound.TunOptions.ExcludePackage) > 0
}),
reloadChan: reloadChan,
}
router.dnsClient = dns.NewClient(dns.ClientOptions{
DisableCache: dnsOptions.DNSClientOptions.DisableCache,
@ -1438,3 +1441,12 @@ func (r *Router) notifyWindowsPowerEvent(event int) {
_ = r.ResetNetwork()
}
}
func (r *Router) Reload() {
if r.platformInterface == nil {
select {
case r.reloadChan <- struct{}{}:
default:
}
}
}