From c95b206592b3be31c1fe5ece891434d03e968c73 Mon Sep 17 00:00:00 2001 From: kercylan98 Date: Tue, 30 Jan 2024 14:22:26 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=20modular=20?= =?UTF-8?q?=E5=8C=85=EF=BC=8C=E7=94=A8=E4=BA=8E=E5=AE=9E=E7=8E=B0=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E5=8C=96=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/internal/service/expose/attack.go | 5 ++ .../example/internal/service/expose/login.go | 5 ++ .../service/services/attack/attack.go | 27 ++++++++ .../internal/service/services/login/login.go | 27 ++++++++ modular/example/main.go | 15 ++++ modular/modular.go | 69 +++++++++++++++++++ modular/service.go | 36 ++++++++++ 7 files changed, 184 insertions(+) create mode 100644 modular/example/internal/service/expose/attack.go create mode 100644 modular/example/internal/service/expose/login.go create mode 100644 modular/example/internal/service/services/attack/attack.go create mode 100644 modular/example/internal/service/services/login/login.go create mode 100644 modular/example/main.go create mode 100644 modular/modular.go create mode 100644 modular/service.go diff --git a/modular/example/internal/service/expose/attack.go b/modular/example/internal/service/expose/attack.go new file mode 100644 index 0000000..d7b2766 --- /dev/null +++ b/modular/example/internal/service/expose/attack.go @@ -0,0 +1,5 @@ +package expose + +type Attack interface { + Name() string +} diff --git a/modular/example/internal/service/expose/login.go b/modular/example/internal/service/expose/login.go new file mode 100644 index 0000000..6beef39 --- /dev/null +++ b/modular/example/internal/service/expose/login.go @@ -0,0 +1,5 @@ +package expose + +type Login interface { + Name() string +} diff --git a/modular/example/internal/service/services/attack/attack.go b/modular/example/internal/service/services/attack/attack.go new file mode 100644 index 0000000..4b11524 --- /dev/null +++ b/modular/example/internal/service/services/attack/attack.go @@ -0,0 +1,27 @@ +package attack + +import ( + "fmt" + "github.com/kercylan98/minotaur/modular/example/internal/service/expose" +) + +type Service struct { + Login expose.Login + name string +} + +func (a *Service) OnInit() { + a.name = "attack" +} + +func (a *Service) OnPreload() { + fmt.Println(a.name, "call", a.Login.Name()) +} + +func (a *Service) OnMount() { + +} + +func (a *Service) Name() string { + return a.name +} diff --git a/modular/example/internal/service/services/login/login.go b/modular/example/internal/service/services/login/login.go new file mode 100644 index 0000000..99b3de3 --- /dev/null +++ b/modular/example/internal/service/services/login/login.go @@ -0,0 +1,27 @@ +package login + +import ( + "fmt" + "github.com/kercylan98/minotaur/modular/example/internal/service/expose" +) + +type Service struct { + Attack expose.Attack + name string +} + +func (l *Service) OnInit() { + l.name = "login" +} + +func (l *Service) OnPreload() { + fmt.Println(l.name, "call", l.Attack.Name()) +} + +func (l *Service) OnMount() { + +} + +func (l *Service) Name() string { + return l.name +} diff --git a/modular/example/main.go b/modular/example/main.go new file mode 100644 index 0000000..35d7a1c --- /dev/null +++ b/modular/example/main.go @@ -0,0 +1,15 @@ +package main + +import ( + "github.com/kercylan98/minotaur/modular" + "github.com/kercylan98/minotaur/modular/example/internal/service/services/attack" + "github.com/kercylan98/minotaur/modular/example/internal/service/services/login" +) + +func main() { + modular.RegisterServices( + new(attack.Service), + new(login.Service), + ) + modular.Run() +} diff --git a/modular/modular.go b/modular/modular.go new file mode 100644 index 0000000..58fc55d --- /dev/null +++ b/modular/modular.go @@ -0,0 +1,69 @@ +package modular + +import ( + "fmt" + "github.com/kercylan98/minotaur/utils/log" + "reflect" +) + +var application *modular + +func init() { + application = &modular{} +} + +type modular struct { + registerServices []Service + services []*service +} + +// RegisterServices 注册服务 +func (m *modular) RegisterServices(s ...Service) { + application.registerServices = append(application.registerServices, s...) +} + +// Run 运行模块化应用程序 +func Run() { + m := application + var names = make(map[string]bool) + var tvm = make(map[reflect.Type]reflect.Value) + for i := 0; i < len(m.registerServices); i++ { + s := newService(m.registerServices[i]) + if names[s.name] { + panic(fmt.Errorf("service %s is already registered", s.name)) + } + names[s.name] = true + tvm[s.vof.Type()] = s.vof + m.services = append(m.services, s) + } + + // OnInit + for i := 0; i < len(m.services); i++ { + s := m.services[i] + s.instance.OnInit() + log.Info(fmt.Sprintf("service %s initialized", s.name)) + } + + // OnPreload + for i := 0; i < len(m.services); i++ { + s := m.services[i] + for f := 0; f < s.vof.Elem().NumField(); f++ { + field := s.vof.Elem().Field(f) + for _, v := range tvm { + if v.Type().AssignableTo(field.Type()) { + field.Set(v) + break + } + } + } + s.instance.OnPreload() + log.Info(fmt.Sprintf("service %s preloaded", s.name)) + } + + // OnMount + for i := 0; i < len(m.services); i++ { + s := m.services[i] + s.instance.OnMount() + log.Info(fmt.Sprintf("service %s mounted", s.name)) + } +} diff --git a/modular/service.go b/modular/service.go new file mode 100644 index 0000000..55b443e --- /dev/null +++ b/modular/service.go @@ -0,0 +1,36 @@ +package modular + +import "reflect" + +// Service 模块化服务接口,所有的服务均需要实现该接口,在服务的生命周期内发生任何错误均应通过 panic 阻止服务继续运行 +// - 生命周期示例: OnInit -> OnPreload -> OnMount +type Service interface { + // OnInit 服务初始化阶段,该阶段不应该依赖其他任何服务 + OnInit() + + // OnPreload 预加载阶段,在进入该阶段时,所有服务已经初始化完成,可在该阶段注入其他服务的依赖 + OnPreload() + + // OnMount 挂载阶段,该阶段所有服务本身及依赖的服务都已经初始化完成,可在该阶段进行服务功能的定义 + OnMount() +} + +// RegisterServices 注册服务 +func RegisterServices(s ...Service) { + application.RegisterServices(s...) +} + +func newService(instance Service) *service { + vof := reflect.ValueOf(instance) + return &service{ + name: vof.Type().String(), + instance: instance, + vof: vof, + } +} + +type service struct { + name string + instance Service + vof reflect.Value +}