kill_self.go 3.3 KB

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