kill_self.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. package service
  2. import (
  3. commonConfig "cicv-data-closedloop/aarch64/pjibot_guide/common/config"
  4. "cicv-data-closedloop/common/config/c_log"
  5. "cicv-data-closedloop/common/util"
  6. "net/rpc"
  7. "os"
  8. "sync"
  9. "time"
  10. )
  11. var (
  12. ChannelKillRosRecord = make(chan int)
  13. ChannelKillDiskClean = make(chan int)
  14. ChannelKillSubscriber = make(chan int)
  15. ChannelKillMove = make(chan int)
  16. ChannelKillConsume = make(chan int)
  17. KillChannel = 5
  18. KillTimes = 0
  19. MutexKill sync.Mutex
  20. )
  21. // 停止信号,主从节点接收到数据后准备重启
  22. type KillSignal struct {
  23. NodeName string
  24. DropUploadData bool
  25. Restart bool
  26. }
  27. // 定义要远程调用的类型和方法
  28. type KillService struct{}
  29. // 杀死自身程序,通过通道实现 方法必须满足RPC规范:函数有两个参数,第一个参数是请求,第二个是响应
  30. func (m *KillService) Kill(args KillSignal, reply *int) error {
  31. c_log.GlobalLogger.Info("接收到自杀信号:", args)
  32. // 1 杀死 rosbag record 命令
  33. ChannelKillRosRecord <- 1
  34. // 2 杀死所有 ros 订阅者
  35. ChannelKillSubscriber <- 1
  36. // 3 杀死上传任任务
  37. if args.DropUploadData == true {
  38. // 3-1 等待上传结束再杀死
  39. ChannelKillMove <- 1
  40. ChannelKillConsume <- 1
  41. } else {
  42. // 3-2 直接杀死
  43. ChannelKillMove <- 2
  44. ChannelKillConsume <- 2
  45. }
  46. go killDone(args.Restart)
  47. return nil
  48. }
  49. func WaitKillSelf() {
  50. killService := new(KillService)
  51. err := rpc.Register(killService)
  52. if err != nil {
  53. c_log.GlobalLogger.Error("注册rpc服务失败:", err)
  54. return
  55. }
  56. // 等待并处理远程调用请求
  57. for {
  58. conn, err := commonConfig.KillSignalListener.Accept()
  59. if err != nil {
  60. continue
  61. }
  62. go rpc.ServeConn(conn)
  63. }
  64. }
  65. func AddKillTimes(info string) {
  66. MutexKill.Lock()
  67. defer MutexKill.Unlock()
  68. switch info {
  69. case "1":
  70. ChannelKillDiskClean <- 1
  71. close(ChannelKillRosRecord)
  72. KillTimes++
  73. c_log.GlobalLogger.Infof("已杀死 record 打包 goroutine,当前自杀进度 %v / %v", KillTimes, KillChannel)
  74. case "2":
  75. close(ChannelKillDiskClean)
  76. KillTimes++
  77. c_log.GlobalLogger.Infof("已杀死 bag 包数量维护 goroutine,当前自杀进度 %v / %v", KillTimes, KillChannel)
  78. case "3":
  79. close(ChannelKillSubscriber)
  80. KillTimes++
  81. c_log.GlobalLogger.Infof("已杀死 rosnode 和ros 订阅者 goroutine,当前自杀进度 %v / %v", KillTimes, KillChannel)
  82. case "4":
  83. close(ChannelKillMove)
  84. KillTimes++
  85. c_log.GlobalLogger.Infof("已杀死 bag 包移动 goroutine,当前自杀进度 %v / %v", KillTimes, KillChannel)
  86. case "5":
  87. close(ChannelKillConsume)
  88. KillTimes++
  89. c_log.GlobalLogger.Infof("已杀死 bag 包消费 goroutine,当前自杀进度 %v / %v", KillTimes, KillChannel)
  90. }
  91. }
  92. func killDone(restart bool) {
  93. for {
  94. time.Sleep(time.Duration(1) * time.Second)
  95. if KillChannel == KillTimes {
  96. if restart {
  97. _, err := util.ExecuteWithPath(commonConfig.LocalConfig.RestartCmd.Dir, commonConfig.LocalConfig.RestartCmd.Name, commonConfig.LocalConfig.RestartCmd.Args...)
  98. if err != nil {
  99. c_log.GlobalLogger.Info("启动新程序失败,【path】=", commonConfig.LocalConfig.RestartCmd.Dir, "【cmd】=", commonConfig.LocalConfig.RestartCmd.Name, commonConfig.LocalConfig.RestartCmd.Args, ":", err)
  100. os.Exit(-1)
  101. }
  102. c_log.GlobalLogger.Info("数据采集任务更新,正常退出当前程序。")
  103. } else {
  104. c_log.GlobalLogger.Info("数据采集任务终止,正常退出当前程序。")
  105. }
  106. os.Exit(0)
  107. }
  108. }
  109. }