package app import ( "easyaudioencode/internal/core/host" "fmt" "log/slog" "net" "os" "os/signal" "path/filepath" "strconv" "syscall" "easyaudioencode/internal/conf" "git.lnton.com/lnton/pkg/logger" "git.lnton.com/lnton/pkg/server" "git.lnton.com/lnton/pkg/system" ) func Run(bc *conf.Bootstrap) { // 以可执行文件所在目录为工作目录,防止以服务方式运行时,工作目录切换到其它位置 bin, _ := os.Executable() if err := os.Chdir(filepath.Dir(bin)); err != nil { slog.Error("change work dir fail", "err", err) } log, clean := SetupLog(bc) defer clean() handler, cleanUp, err := WireApp(bc, log) if err != nil { slog.Error("程序构建失败", "err", err.Error()) panic(err) } defer cleanUp() var svc *server.Server if bc.Server.HTTP.Port != 0 { svc = server.New(handler, server.Port(strconv.Itoa(bc.Server.HTTP.Port)), server.ReadTimeout(bc.Server.HTTP.Timeout.Duration()), server.WriteTimeout(bc.Server.HTTP.Timeout.Duration()), ) host.StartOk <- struct{}{} // http端口已监听,开始心跳保活 go svc.Start() } else { svc = server.New(handler, server.ReadTimeout(bc.Server.HTTP.Timeout.Duration()), server.WriteTimeout(bc.Server.HTTP.Timeout.Duration()), ) lis, err := net.Listen("tcp", ":8089") if err != nil { fmt.Printf("创建监听器失败: %v\n", err) return } //bc.Server.HTTP.Port = lis.Addr().(*net.TCPAddr).Port bc.Server.HTTP.Port = lis.Addr().(*net.TCPAddr).Port host.StartOk <- struct{}{} // http端口已监听,开始心跳保活 go svc.StartWithListen(lis) } interrupt := make(chan os.Signal, 1) signal.Notify(interrupt, syscall.SIGINT, syscall.SIGTERM) fmt.Println("服务启动成功 port:", bc.Server.HTTP.Port) select { case s := <-interrupt: slog.Info(`<-interrupt`, "signal", s.String()) case err := <-svc.Notify(): system.ErrPrintf("err: %s\n", err.Error()) slog.Error(`<-server.Notify()`, "err", err) } if err := svc.Shutdown(); err != nil { slog.Error(`server.Shutdown()`, "err", err) } } // SetupLog 初始化日志 func SetupLog(bc *conf.Bootstrap) (*slog.Logger, func()) { logDir := filepath.Join(system.Getwd(), bc.Log.Dir) return logger.SetupSlog(logger.Config{ Dir: logDir, // 日志地址 Debug: bc.Debug, // 服务级别Debug/Release MaxAge: bc.Log.MaxAge.Duration(), // 日志存储时间 RotationTime: bc.Log.RotationTime.Duration(), // 循环时间 RotationSize: bc.Log.RotationSize * 1024 * 1024, // 循环大小 Level: bc.Log.Level, // 日志级别 }) }