app.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. // Author: NiuJiuRu
  2. // Email: niujiuru@qq.com
  3. package baseapp
  4. import (
  5. "fmt"
  6. "os"
  7. "os/signal"
  8. "path/filepath"
  9. "sync/atomic"
  10. "syscall"
  11. "github.com/alexflint/go-filemutex"
  12. )
  13. var Version, BuildTime string // 由Makefile传入
  14. var isExit atomic.Bool
  15. var exitCh = make(chan struct{})
  16. var signalReady atomic.Bool
  17. func ModuleInit() {
  18. InitPath()
  19. InitLogger("")
  20. }
  21. func SingleInstanceRun() { // 非阻塞单实例运行, 调用此函数后, 安全退出时, 需调用SafeExit()函数
  22. lockFile := filepath.Join(RUN_DIR, EXEC_FILENAME+".lock")
  23. mux, err := filemutex.New(lockFile)
  24. if err != nil {
  25. Logger.Fatalf("An error occurred while calling the filemutex.New() function: %v", err)
  26. }
  27. if err = mux.TryLock(); err != nil {
  28. Logger.Warnf("Another instance is already running!")
  29. mux.Close()
  30. Logger.Infof("Exited")
  31. os.Exit(0)
  32. }
  33. pid := os.Getpid()
  34. err = os.WriteFile(lockFile, fmt.Appendf(nil, "%d", pid), 0644)
  35. if err != nil {
  36. Logger.Warnf("Can't to write PID to the \"%s\" file: %v!", lockFile, err)
  37. }
  38. ch := make(chan os.Signal, 1)
  39. signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
  40. signalReady.Store(true)
  41. go func() {
  42. sig := <-ch
  43. Logger.Infof("Received signal: %v", sig)
  44. _ = mux.Close()
  45. _ = os.Remove(lockFile)
  46. isExit.Store(true)
  47. close(exitCh)
  48. }()
  49. }
  50. func IsExit1() bool {
  51. return isExit.Load()
  52. }
  53. func IsExit2() <-chan struct{} {
  54. return exitCh
  55. }
  56. func SafeExit() { // 安全退出
  57. if !signalReady.Load() {
  58. return
  59. }
  60. pid := os.Getpid()
  61. syscall.Kill(pid, syscall.SIGTERM)
  62. <-exitCh
  63. }