Fetch the repository succeeded.
package gsf
import (
"errors"
"fmt"
"gitee.com/kzangv/gsf-fof/logger"
"github.com/urfave/cli/v2"
"math/rand"
"os"
"os/signal"
"runtime"
"strings"
"sync"
"syscall"
"time"
)
const (
// Env
EnvLocal = 0 // 本地
EnvDebug = 1 // 测试
EnvPrev = 2 // 预发布
EnvProd = 3 // 线上
CliAppEnv = "app-env"
CliAppVer = "app-version"
CliAppLogMore = "app-log-more"
)
var (
EnvVersion = "1.0.0"
_EnvDevStr = "local" // 本地
_EnvTestStr = "debug" // 测试
_EnvPrevStr = "yf" // 预发布
_EnvProdStr = "release" // 线上
)
var (
_EnvMap = map[int][2]string{
EnvLocal: {_EnvDevStr, "本地环境"},
EnvDebug: {_EnvTestStr, "测试环境"},
EnvPrev: {_EnvPrevStr, "预发布环境"},
EnvProd: {_EnvProdStr, "线上环境"},
}
)
type _EnvFlag int
func (v _EnvFlag) Usage() string {
ret := make([]string, 0, len(_EnvMap))
for _, k := range []int{EnvLocal, EnvDebug, EnvPrev, EnvProd} {
s := _EnvMap[k]
ret = append(ret, strings.Join(s[:], "-"))
}
return "env(" + strings.Join(ret, ", ") + ")"
}
func (v *_EnvFlag) Action(_ *cli.Context, sv string) error {
match := false
for ek, ev := range _EnvMap {
if sv == ev[0] {
*v, match = _EnvFlag(ek), true
break
}
}
if match != true {
return errors.New("Env Is Invalid: " + sv)
}
return nil
}
type AppConfig struct {
env _EnvFlag
version string
execDir string
logMore bool
}
func (v *AppConfig) Env() int {
return int(v.env)
}
func (v *AppConfig) EnvDesc() string {
return _EnvMap[int(v.env)][0]
}
func (v *AppConfig) SetEnv(e int) bool {
if _, ok := _EnvMap[int(v.env)]; ok {
v.env = _EnvFlag(e)
return true
}
return false
}
func (v *AppConfig) ExecDir() string {
return v.execDir
}
func (v *AppConfig) Version() string {
return v.version
}
func (v *AppConfig) LogMore() bool {
return v.logMore
}
type Component interface {
CliFlags() []cli.Flag
Init(logger.Interface, *AppConfig, *cli.Context) error
Run() error
Close() error
}
type Service interface {
CliFlags() []cli.Flag
Init(*AppConfig, *cli.Context) (logger.Interface, error)
Run(logger.Interface, *AppConfig) error
Close()
}
type Application struct {
Component map[string]Component
Log logger.Interface
Cfg AppConfig
Ser Service
}
func (app *Application) closeComponent() {
if app.Component != nil && len(app.Component) > 0 {
wg := sync.WaitGroup{}
wg.Add(len(app.Component))
for k := range app.Component {
go func(v Component) {
defer wg.Done()
_ = v.Close()
}(app.Component[k])
}
wg.Wait()
}
}
func (app *Application) shutdown() {
defer func() {
fmt.Println("Application Had Exit")
os.Exit(0)
}()
fmt.Println("Application To Exit")
}
func (app *Application) catchSignal() {
c := make(chan os.Signal)
signal.Notify(c, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM)
for s := range c {
switch s {
case syscall.SIGHUP:
fallthrough
case syscall.SIGINT, syscall.SIGTERM:
app.closeComponent()
app.Ser.Close()
app.shutdown()
}
}
}
func (app *Application) runComponent() error {
if app.Component != nil && len(app.Component) > 0 {
wg := sync.WaitGroup{}
lock := sync.Mutex{}
var errList []error
wg.Add(len(app.Component))
for k := range app.Component {
go func(v Component) {
defer wg.Done()
err := v.Run()
if err != nil {
lock.Lock()
if errList == nil {
errList = make([]error, 0)
}
errList = append(errList, err)
lock.Unlock()
}
}(app.Component[k])
}
wg.Wait()
if len(errList) > 0 {
errStr := make([]string, 0, len(errList))
for k := range errList {
errStr = append(errStr, errList[k].Error())
}
return errors.New("Component Run Error:" + strings.Join(errStr, ","))
}
}
return nil
}
func (app *Application) run() error {
var err error = nil
runtime.GOMAXPROCS(runtime.NumCPU())
go app.catchSignal()
// 初始化随机种子
rand.Seed(time.Now().UnixNano())
// 启动服务
err = app.runComponent()
if err != nil {
return err
}
return app.Ser.Run(app.Log, &app.Cfg)
}
func (app *Application) Start(cmd *cli.App, args []string, service Service) {
if cmd == nil {
cmd = cli.NewApp()
cmd.Version = "1.0"
cmd.Name = "ApplicationWeb"
cmd.Usage = "ApplicationWeb Server"
cmd.DisableSliceFlagSeparator = true
}
app.Ser = service
// app
cfs := make([][]cli.Flag, 0, len(app.Component)+2)
cfs = append(cfs, []cli.Flag{
// base
&cli.StringFlag{Name: CliAppEnv, Value: _EnvDevStr, Usage: app.Cfg.env.Usage(), Action: app.Cfg.env.Action},
&cli.StringFlag{Name: CliAppVer, Value: EnvVersion, Usage: "version", Destination: &app.Cfg.version},
&cli.BoolFlag{Name: CliAppLogMore, Value: false, Usage: "log more", Destination: &app.Cfg.logMore},
})
fsLen := len(cfs[0])
// service
afs := app.Ser.CliFlags()
if len(afs) > 0 {
cfs = append(cfs, afs)
fsLen += len(afs)
}
// component
for k := range app.Component {
v := app.Component[k].CliFlags()
if len(v) > 0 {
cfs = append(cfs, v)
fsLen += len(v)
}
}
// cli merge
fs := make([]cli.Flag, 0, fsLen)
for _, v := range cfs {
fs = append(fs, v...)
}
// 执行命令行
cmd.Flags = fs
cmd.Action = func(ctx *cli.Context) error {
var err error = nil
app.Cfg.execDir, err = os.Getwd()
if err == nil {
// 用命令行初始化配置
app.Log, err = app.Ser.Init(&app.Cfg, ctx)
if err == nil {
// 组件初始化
for k := range app.Component {
if err = app.Component[k].Init(app.Log, &app.Cfg, ctx); err != nil {
err = errors.New("Component Init Error: " + err.Error())
break
}
}
// 启动程序
if err == nil {
err = app.run()
}
}
} else {
err = errors.New("dir is invalid: " + app.Cfg.execDir)
}
return err
}
err := cmd.Run(args)
if err != nil {
fmt.Printf("Init Error: %s", err.Error())
os.Exit(1)
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。