You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
189 lines
4.9 KiB
189 lines
4.9 KiB
package cbase
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/signal"
|
|
"runtime"
|
|
"sync"
|
|
"syscall"
|
|
|
|
"yunyan/lego"
|
|
"yunyan/lego/core"
|
|
"yunyan/lego/sys/event"
|
|
"yunyan/lego/sys/log"
|
|
)
|
|
|
|
type defaultModule struct {
|
|
seetring map[string]interface{}
|
|
mi core.IModule
|
|
closeSig chan bool
|
|
wg sync.WaitGroup
|
|
}
|
|
|
|
func (this *defaultModule) run() {
|
|
this.mi.Run(this.closeSig)
|
|
this.wg.Done()
|
|
}
|
|
func (this *defaultModule) destroy() (err error) {
|
|
defer lego.Recover(fmt.Sprintf("Module :%s destroy", this.mi.GetType()))
|
|
err = this.mi.Destroy()
|
|
if err != nil {
|
|
err = fmt.Errorf("关闭模块【%s】失败 err:%s", this.mi.GetType(), err.Error())
|
|
}
|
|
return
|
|
}
|
|
|
|
type ServiceBase struct {
|
|
closesig chan string
|
|
Service core.IService
|
|
comps map[core.S_Comps]core.IServiceComp
|
|
modules map[core.M_Modules]*defaultModule
|
|
}
|
|
|
|
func (this *ServiceBase) Init(service core.IService) (err error) {
|
|
this.closesig = make(chan string, 1)
|
|
this.Service = service
|
|
this.modules = make(map[core.M_Modules]*defaultModule)
|
|
this.Service.InitSys()
|
|
for _, v := range this.comps {
|
|
options := v.NewOptions()
|
|
if o, ok := service.GetSettings().Comps[string(v.GetName())]; ok {
|
|
options.LoadConfig(o)
|
|
}
|
|
err = v.Init(this.Service, v, options)
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
log.Infof("服务[%s] 初始化完成!", this.Service.GetId())
|
|
return nil
|
|
}
|
|
|
|
// 配置服务组件
|
|
func (this *ServiceBase) OnInstallComp(cops ...core.IServiceComp) {
|
|
this.comps = make(map[core.S_Comps]core.IServiceComp)
|
|
for _, v := range cops {
|
|
if _, ok := this.comps[v.GetName()]; ok {
|
|
log.Errorf("覆盖注册组件【%s】", v.GetName())
|
|
}
|
|
this.comps[v.GetName()] = v
|
|
}
|
|
}
|
|
|
|
func (this *ServiceBase) Start() (err error) {
|
|
for _, v := range this.comps {
|
|
err = v.Start()
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
log.Infof("服务[%s:%s] 启动完成!", this.Service.GetId(), this.Service.GetVersion())
|
|
return
|
|
}
|
|
|
|
func (this *ServiceBase) Run(mod ...core.IModule) {
|
|
go func() {
|
|
defer func() { //程序异常 收集异常信息传递给前端显示
|
|
if r := recover(); r != nil {
|
|
buf := make([]byte, 4096)
|
|
l := runtime.Stack(buf, false)
|
|
log.Errorf("服务[%s:%s]崩溃啦!------> %s", this.Service.GetId(), this.Service.GetVersion(), fmt.Sprintf("%v: %s", r, buf[:l]))
|
|
}
|
|
}()
|
|
for _, v := range mod {
|
|
if sf, ok := this.Service.GetSettings().Modules[string(v.GetType())]; ok {
|
|
this.modules[v.GetType()] = &defaultModule{
|
|
seetring: sf,
|
|
mi: v,
|
|
closeSig: make(chan bool, 1),
|
|
}
|
|
} else {
|
|
this.modules[v.GetType()] = &defaultModule{
|
|
seetring: make(map[string]interface{}),
|
|
mi: v,
|
|
closeSig: make(chan bool, 1),
|
|
}
|
|
log.Warnf("注册模块【%s】 没有对应的配置信息", v.GetType())
|
|
}
|
|
}
|
|
for _, v := range this.modules {
|
|
options := v.mi.NewOptions()
|
|
if err := options.LoadConfig(v.seetring); err == nil {
|
|
err = v.mi.Init(this.Service, v.mi, options)
|
|
if err != nil {
|
|
log.Panicf(fmt.Sprintf("初始化模块【%s】错误 err:%v", v.mi.GetType(), err))
|
|
}
|
|
} else {
|
|
log.Panicf(fmt.Sprintf("模块【%s】 Options:%v 配置错误 err:%v", v.mi.GetType(), v.seetring, err))
|
|
}
|
|
}
|
|
for _, v := range this.modules {
|
|
err := v.mi.Start()
|
|
if err != nil {
|
|
log.Panicf(fmt.Sprintf("启动模块【%s】错误 err:%v", v.mi.GetType(), err))
|
|
} else {
|
|
log.Debugf("启动模块【%s】", v.mi.GetType())
|
|
}
|
|
}
|
|
for _, v := range this.modules {
|
|
v.wg.Add(1)
|
|
go v.run()
|
|
}
|
|
event.TriggerEvent(core.Event_ServiceStartEnd) //广播事件
|
|
}()
|
|
//监听外部关闭服务信号
|
|
c := make(chan os.Signal, 1)
|
|
//添加进程结束信号
|
|
signal.Notify(c,
|
|
os.Interrupt, //退出信号 ctrl+c退出
|
|
os.Kill, //kill 信号
|
|
syscall.SIGHUP, //终端控制进程结束(终端连接断开)
|
|
syscall.SIGINT, //用户发送INTR字符(Ctrl+C)触发
|
|
syscall.SIGTERM, //结束程序(可以被捕获、阻塞或忽略)
|
|
syscall.SIGQUIT) //用户发送QUIT字符(Ctrl+/)触发
|
|
select {
|
|
case sig := <-c:
|
|
log.Errorf("服务[%s] 关闭 signal = %v\n", this.Service.GetId(), sig)
|
|
case <-this.closesig:
|
|
log.Errorf("服务[%s] 关闭\n", this.Service.GetId())
|
|
}
|
|
}
|
|
|
|
func (this *ServiceBase) Close(closemsg string) {
|
|
this.closesig <- closemsg
|
|
}
|
|
|
|
func (this *ServiceBase) Destroy() (err error) {
|
|
for _, v := range this.modules {
|
|
v.closeSig <- true
|
|
v.wg.Wait()
|
|
err = v.destroy()
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
for _, v := range this.comps {
|
|
err = v.Destroy()
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (this *ServiceBase) GetModule(ModuleName core.M_Modules) (module core.IModule, err error) {
|
|
if v, ok := this.modules[ModuleName]; ok {
|
|
return v.mi, nil
|
|
} else {
|
|
return nil, fmt.Errorf("未装配模块【%s】", ModuleName)
|
|
}
|
|
}
|
|
|
|
func (this *ServiceBase) GetComp(CompName core.S_Comps) (comp core.IServiceComp, err error) {
|
|
if v, ok := this.comps[CompName]; ok {
|
|
return v, nil
|
|
} else {
|
|
return nil, fmt.Errorf("Service 未装配组件【%s】", CompName)
|
|
}
|
|
}
|
|
|