diff --git a/server/multiple.go b/server/multiple.go index 7e3bc83a..340d50c5 100644 --- a/server/multiple.go +++ b/server/multiple.go @@ -11,19 +11,21 @@ import ( func NewMultipleServer(serverHandle ...func() (addr string, srv *Server)) *MultipleServer { ms := &MultipleServer{ - servers: make([]*Server, len(serverHandle), len(serverHandle)), - addresses: make([]string, len(serverHandle), len(serverHandle)), - } - for i := 0; i < len(serverHandle); i++ { - ms.addresses[i], ms.servers[i] = serverHandle[i]() + servers: make([]*Server, len(serverHandle), len(serverHandle)), + addresses: make([]string, len(serverHandle), len(serverHandle)), + serverHandles: serverHandle, } return ms } type MultipleServer struct { - servers []*Server - addresses []string - exitEventHandles []func() + servers []*Server + addresses []string + exitEventHandles []func() + startFinishEventHandlers []func() + services []func() + preload []func() + serverHandles []func() (addr string, srv *Server) } func (slf *MultipleServer) Run() { @@ -33,6 +35,15 @@ func (slf *MultipleServer) Run() { close(exceptionChannel) close(runtimeExceptionChannel) }() + for _, service := range slf.services { + service() + } + for _, preload := range slf.preload { + preload() + } + for i := 0; i < len(slf.serverHandles); i++ { + slf.addresses[i], slf.servers[i] = slf.serverHandles[i]() + } var wait sync.WaitGroup var hasKcp bool for i := 0; i < len(slf.servers); i++ { @@ -69,6 +80,7 @@ func (slf *MultipleServer) Run() { kcp.SystemTimedSched.Close() } + slf.OnStartFinishEvent() showServersInfo(serverMultipleMark, slf.servers...) systemSignal := make(chan os.Signal, 1) @@ -121,3 +133,14 @@ func (slf *MultipleServer) OnExitEvent() { handle() } } + +// RegStartFinishEvent 注册启动完成事件 +func (slf *MultipleServer) RegStartFinishEvent(handle func()) { + slf.startFinishEventHandlers = append(slf.startFinishEventHandlers, handle) +} + +func (slf *MultipleServer) OnStartFinishEvent() { + for _, handle := range slf.startFinishEventHandlers { + handle() + } +} diff --git a/server/multiple_service.go b/server/multiple_service.go new file mode 100644 index 00000000..16f8034f --- /dev/null +++ b/server/multiple_service.go @@ -0,0 +1,50 @@ +package server + +import ( + "github.com/kercylan98/minotaur/utils/log" + "reflect" +) + +// MultipleService 兼容传统 service 设计模式的接口,通过该接口可以实现更简洁、更具有可读性的服务绑定 +type MultipleService interface { + // OnInit 初始化服务,该方法将会在 Server 初始化时执行 + // - 通常来说,该阶段发生任何错误都应该 panic 以阻止 Server 启动 + OnInit(srv *MultipleServer) + // OnPreloading 预加载阶段,该方法将会在所有服务的 OnInit 函数执行完毕后执行 + // - 通常来说,该阶段发生任何错误都应该 panic 以阻止 Server 启动 + OnPreloading(srv *MultipleServer) +} + +// BindServiceToMultipleServer 绑定服务到多个 MultipleServer +func BindServiceToMultipleServer(server *MultipleServer, services ...MultipleService) { + for i := 0; i < len(services); i++ { + service := services[i] + server.preload = append(server.preload, func() { + name := reflect.TypeOf(service).String() + defer func(name string) { + if err := recover(); err != nil { + log.Error("MultipleServer", log.String("service", name), log.String("status", "preloading"), log.Any("err", err)) + panic(err) + } + }(name) + service.OnPreloading(server) + log.Info("MultipleServer", log.String("service", name), log.String("status", "preloaded")) + }) + } + + for i := 0; i < len(services); i++ { + service := services[i] + server.services = append(server.services, func() { + name := reflect.TypeOf(service).String() + defer func(name string) { + if err := recover(); err != nil { + log.Error("MultipleServer", log.String("service", name), log.String("status", "initialization"), log.Any("err", err)) + panic(err) + } + }(name) + service.OnInit(server) + log.Info("MultipleServer", log.String("service", name), log.String("status", "initialized")) + }) + } + +}