app.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  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. func ModuleInit() {
  17. InitPath()
  18. InitLogger()
  19. }
  20. func SingleInstanceRun() { // 非阻塞单实例运行
  21. lockFile := filepath.Join(RUN_DIR, EXEC_FILENAME+".lock")
  22. mux, err := filemutex.New(lockFile)
  23. if err != nil {
  24. Logger.Fatalf("An error occurred while calling the filemutex.New() function: %v", err)
  25. }
  26. if err = mux.TryLock(); err != nil {
  27. Logger.Warnf("Another instance is already running!")
  28. mux.Close()
  29. Logger.Infof("Exited")
  30. os.Exit(0)
  31. }
  32. pid := os.Getpid()
  33. err = os.WriteFile(lockFile, fmt.Appendf(nil, "%d", pid), 0644)
  34. if err != nil {
  35. Logger.Warnf("Can't to write PID to the \"%s\" file: %v!", lockFile, err)
  36. }
  37. ch := make(chan os.Signal, 1)
  38. signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM, syscall.SIGUSR1)
  39. go func() {
  40. for s := range ch {
  41. switch s {
  42. case syscall.SIGINT, syscall.SIGTERM, syscall.SIGUSR1:
  43. Logger.Infof("Received signal: %v", s)
  44. mux.Close()
  45. os.RemoveAll(lockFile)
  46. isExit.Store(true)
  47. close(exitCh)
  48. return
  49. default:
  50. Logger.Warnf("Received unexpected signal: %v!", s)
  51. }
  52. }
  53. }()
  54. }
  55. func IsExit1() bool {
  56. return isExit.Load()
  57. }
  58. func IsExit2() <-chan struct{} {
  59. return exitCh
  60. }
  61. func SafeExit() { // 安全退出
  62. pid := os.Getpid()
  63. syscall.Kill(pid, syscall.SIGUSR1)
  64. <-exitCh
  65. }