github.com/zly-app/zapp@v1.3.3/app.go (about) 1 /* 2 ------------------------------------------------- 3 Author : zlyuancn 4 date: 2021/1/20 5 Description : 6 ------------------------------------------------- 7 */ 8 9 package zapp 10 11 import ( 12 "context" 13 "os" 14 "os/signal" 15 "sync" 16 "syscall" 17 18 _ "go.uber.org/automaxprocs" 19 "go.uber.org/zap" 20 "gopkg.in/yaml.v3" 21 22 "github.com/zly-app/zapp/config" 23 "github.com/zly-app/zapp/core" 24 "github.com/zly-app/zapp/logger" 25 ) 26 27 var defaultApp core.IApp 28 29 func App() core.IApp { 30 return defaultApp 31 } 32 33 type appCli struct { 34 name string 35 36 opt *option 37 38 baseCtx context.Context 39 baseCtxCancel context.CancelFunc 40 41 config core.IConfig 42 core.ILogger 43 component core.IComponent 44 plugins map[core.PluginType]core.IPlugin 45 services map[core.ServiceType]core.IService 46 47 interrupt chan os.Signal 48 onceExit sync.Once 49 } 50 51 // 创建一个app 52 // 53 // 根据提供的app名和选项创建一个app 54 // 正常启动时会初始化所有服务 55 func NewApp(appName string, opts ...Option) core.IApp { 56 app := &appCli{ 57 name: appName, 58 interrupt: make(chan os.Signal, 1), 59 plugins: make(map[core.PluginType]core.IPlugin), 60 services: make(map[core.ServiceType]core.IService), 61 opt: newOption(opts...), 62 } 63 app.baseCtx, app.baseCtxCancel = context.WithCancel(context.Background()) 64 defaultApp = app 65 66 // 启用守护进程 67 app.enableDaemon() 68 69 app.config = config.NewConfig(appName, app.opt.ConfigOpts...) 70 if name := app.config.Config().Frame.Name; name != "" { 71 app.name = name 72 } 73 if app.name == "" { 74 logger.Log.Fatal("appName is empty") 75 } 76 app.config.Config().Frame.Name = app.name 77 78 app.ILogger = logger.NewLogger(appName, app.config, app.opt.LogOpts...) 79 80 if app.config.Config().Frame.PrintConfig { 81 data, err := yaml.Marshal(app.config.GetViper().AllSettings()) 82 if err != nil { 83 app.Error("打印配置时序列化失败", zap.Error(err)) 84 } else { 85 app.Info("配置数据:\n", string(data), "\n") 86 } 87 } 88 89 app.handler(BeforeInitializeHandler) 90 app.Debug("app初始化") 91 92 // 构建组件 93 app.makeComponent() 94 // 构建插件 95 app.makePlugin() 96 // 构建服务 97 app.makeService() 98 99 app.Debug("app初始化完毕") 100 app.handler(AfterInitializeHandler) 101 102 return app 103 } 104 105 func (app *appCli) run() { 106 app.handler(BeforeStartHandler) 107 app.Debug("启动app") 108 109 // 启动插件 110 app.startPlugin() 111 // 启动服务 112 app.startService() 113 // 开始释放内存 114 app.startFreeMemory() 115 116 app.Info("app已启动") 117 app.handler(AfterStartHandler) 118 119 signal.Notify(app.interrupt, os.Kill, os.Interrupt, syscall.SIGINT, syscall.SIGKILL, syscall.SIGTERM) 120 <-app.interrupt 121 122 app.onceExit.Do(func() { 123 app.exit() 124 }) 125 } 126 127 func (app *appCli) exit() { 128 // app退出前 129 app.handler(BeforeExitHandler) 130 app.Debug("app准备退出") 131 132 // 关闭基础上下文 133 app.baseCtxCancel() 134 // 关闭服务 135 app.closeService() 136 // 关闭插件 137 app.closePlugin() 138 // 释放组件资源 139 app.releaseComponentResource() 140 141 // app退出后 142 app.Warn("app已退出") 143 app.handler(AfterExitHandler) 144 } 145 146 func (app *appCli) Name() string { 147 return app.name 148 } 149 150 // 启动 151 func (app *appCli) Run() { 152 app.run() 153 } 154 155 // 退出 156 func (app *appCli) Exit() { 157 app.onceExit.Do(func() { 158 // 尝试发送退出信号 159 select { 160 case app.interrupt <- syscall.SIGQUIT: 161 default: 162 } 163 164 app.exit() 165 }) 166 } 167 168 func (app *appCli) BaseContext() context.Context { 169 return app.baseCtx 170 } 171 172 func (app *appCli) GetConfig() core.IConfig { 173 return app.config 174 } 175 176 func (app *appCli) GetLogger() core.ILogger { 177 return app.ILogger 178 }