complete reload
clear resources before exit
update todo list
fix mistake
This commit is contained in:
Yuzuki616
2024-11-24 01:16:26 +09:00
parent 96617ee2db
commit a1fb940c13
3 changed files with 153 additions and 35 deletions

View File

@@ -11,6 +11,7 @@
- [ ] 插件管理器的实现 - [ ] 插件管理器的实现
- [ ] Cli UI 的实现 - [ ] Cli UI 的实现
- [ ] Log 的规范化 - [ ] Log 的规范化
- [ ] 局部重载的实现
## 关联仓库 ## 关联仓库
- 插件接口定义 - 插件接口定义

View File

@@ -5,6 +5,7 @@ import (
"Ratte/conf" "Ratte/conf"
"Ratte/handler" "Ratte/handler"
"Ratte/trigger" "Ratte/trigger"
"fmt"
"github.com/Yuzuki616/Ratte-Interface/core" "github.com/Yuzuki616/Ratte-Interface/core"
"github.com/Yuzuki616/Ratte-Interface/panel" "github.com/Yuzuki616/Ratte-Interface/panel"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
@@ -49,30 +50,16 @@ func runHandle(_ *cobra.Command, _ []string) {
log.WithField("path", config).Info("Loaded.") log.WithField("path", config).Info("Loaded.")
log.Info("Init core plugin...") log.Info("Init core plugin...")
// new cores err = startCores(c.Core)
cores = make(map[string]*core.PluginClient, len(c.Core)) if err != nil {
for _, co := range c.Core { log.WithError(err).Fatal("Init core plugin failed")
c, err := core.NewClient(nil, exec.Command(co.Path))
if err != nil {
log.WithError(err).WithField("core", co.Name).Fatal("New core failed")
}
err = c.Start(co.DataPath, co.Config)
if err != nil {
log.WithError(err).WithField("core", co.Name).Fatal("Start core failed")
}
cores[co.Name] = c
} }
log.Info("Done.") log.Info("Done.")
log.Info("Init panel plugin...") log.Info("Init panel plugin...")
// new panels err = startPanel(c.Panel)
panels = make(map[string]*panel.PluginClient, len(c.Panel)) if err != nil {
for _, p := range c.Panel { log.WithError(err).Fatal("Init panel plugin failed")
pn, err := panel.NewClient(nil, exec.Command(p.Path))
if err != nil {
log.WithError(err).WithField("panel", p.Name).Fatal("New panel failed")
}
panels[p.Name] = pn
} }
log.Info("Done.") log.Info("Done.")
@@ -90,26 +77,145 @@ func runHandle(_ *cobra.Command, _ []string) {
log.Info("Starting...") log.Info("Starting...")
// new node // new node
triggers = make([]*trigger.Trigger, 0, len(c.Node)) err = startTriggerAndHandler(c.Node)
handlers = make([]*handler.Handler, len(c.Node)) if err != nil {
for _, nd := range c.Node { log.WithError(err).Fatal("Start trigger and handler failed")
}
log.Info("Started.")
c.SetErrorHandler(func(err error) {
log.WithFields(map[string]interface{}{
"error": err,
"Services": "ConfWatcher",
}).Error("")
})
c.SetEventHandler(func(event uint, target ...string) {
l := log.WithFields(map[string]interface{}{
"Service": "ConfWatcher",
})
l.Info("Config changed, restart...")
err := closeTriggerAndHandler()
if err != nil {
log.WithError(err).Fatal("Close trigger and handler failed")
}
err = closeCore()
if err != nil {
log.WithError(err).Fatal("Close core failed")
}
err = closePanel()
if err != nil {
log.WithError(err).Fatal("Close panel failed")
}
err = startCores(c.Core)
if err != nil {
log.WithError(err).Fatal("Start core failed")
}
err = startPanel(c.Panel)
if err != nil {
log.WithError(err).Fatal("Start panel failed")
}
err = startTriggerAndHandler(c.Node)
if err != nil {
log.WithError(err).Fatal("Start trigger and handler failed")
}
l.Info("Restart Done.")
})
err = c.Watch()
if err != nil {
log.WithError(err).Fatal("Watch config failed")
}
runtime.GC()
sig := make(chan os.Signal, 1)
signal.Notify(sig, syscall.SIGINT, syscall.SIGKILL, syscall.SIGTERM)
<-sig
// clear
log.Info("Shutting down...")
err = closeTriggerAndHandler()
if err != nil {
log.WithError(err).Fatal("Close trigger and handler failed")
}
err = closeCore()
if err != nil {
log.WithError(err).Fatal("Close core failed")
}
err = closePanel()
if err != nil {
log.WithError(err).Fatal("Close panel failed")
}
log.Info("Done.")
}
func startCores(coresP []conf.Core) error {
// new cores
cores = make(map[string]*core.PluginClient, len(coresP))
for _, co := range coresP {
c, err := core.NewClient(nil, exec.Command(co.Path))
if err != nil {
return fmt.Errorf("new core error: %w", err)
}
err = c.Start(co.DataPath, co.Config)
if err != nil {
return fmt.Errorf("start core error: %w", err)
}
cores[co.Name] = c
}
return nil
}
func closeCore() error {
for _, c := range cores {
err := c.Close()
if err != nil {
return err
}
}
return nil
}
func startPanel(panelsP []conf.Panel) error {
panels = make(map[string]*panel.PluginClient, len(panelsP))
for _, p := range panelsP {
pn, err := panel.NewClient(nil, exec.Command(p.Path))
if err != nil {
return fmt.Errorf("new panel error: %w", err)
}
panels[p.Name] = pn
}
return nil
}
func closePanel() error {
for _, p := range panels {
err := p.Close()
if err != nil {
return err
}
}
return nil
}
func startTriggerAndHandler(c []conf.Node) error {
triggers = make([]*trigger.Trigger, 0, len(c))
handlers = make([]*handler.Handler, len(c))
for _, nd := range c {
var co core.Core var co core.Core
var pl panel.Panel var pl panel.Panel
var ac *acme.Acme var ac *acme.Acme
if c, ok := cores[nd.Options.Core]; ok { if c, ok := cores[nd.Options.Core]; ok {
co = c co = c
} else { } else {
log.WithField("core", nd.Options.Core).Fatal("Couldn't find core") return fmt.Errorf("unknown core name: %s", nd.Options.Core)
} }
if p, ok := panels[nd.Options.Panel]; ok { if p, ok := panels[nd.Options.Panel]; ok {
pl = p pl = p
} else { } else {
log.WithField("panel", nd.Options.Panel).Fatal("Couldn't find panel") return fmt.Errorf("")
} }
if a, ok := acmes[nd.Options.Acme]; ok { if a, ok := acmes[nd.Options.Acme]; ok {
ac = a ac = a
} else { } else {
log.WithField("acme", nd.Options.Acme).Fatal("Couldn't find acme") return fmt.Errorf("unknown acme name: %s", nd.Options.Acme)
} }
h := handler.New(co, pl, nd.Name, ac, log.WithFields( h := handler.New(co, pl, nd.Name, ac, log.WithFields(
@@ -126,18 +232,29 @@ func runHandle(_ *cobra.Command, _ []string) {
}, },
), &nd.Trigger, h, pl, &nd.Remote) ), &nd.Trigger, h, pl, &nd.Remote)
if err != nil { if err != nil {
log.WithError(err).Fatal("New trigger failed") return fmt.Errorf("new trigger error: %w", err)
} }
triggers = append(triggers, tr) triggers = append(triggers, tr)
err = tr.Start() err = tr.Start()
if err != nil { if err != nil {
log.WithError(err).Fatal("Start trigger failed") return fmt.Errorf("start trigger error: %w", err)
} }
} }
log.Info("Started.") return nil
}
runtime.GC()
sig := make(chan os.Signal, 1) func closeTriggerAndHandler() error {
signal.Notify(sig, syscall.SIGINT, syscall.SIGKILL, syscall.SIGTERM) for _, t := range triggers {
<-sig err := t.Close()
if err != nil {
return fmt.Errorf("close trigger error: %w", err)
}
}
for _, h := range handlers {
err := h.Close()
if err != nil {
return fmt.Errorf("close handler error: %w", err)
}
}
return nil
} }

View File

@@ -30,7 +30,7 @@ func (h *Handler) PullNodeHandle(n *panel.NodeInfo) error {
protocol = "shadowsocks" protocol = "shadowsocks"
port = n.Shadowsocks.Port port = n.Shadowsocks.Port
case "trojan": case "trojan":
protocol = "trojana" protocol = "trojan"
port = n.Trojan.Port port = n.Trojan.Port
case "other": case "other":
protocol = "other" protocol = "other"