package svc import ( "cicv-data-closedloop/common/config/c_log" commonConfig "cicv-data-closedloop/pji/common/cfg" "cicv-data-closedloop/pji/common/util" "net/rpc" "os" "sync" "time" ) var ( ChannelKillRosRecord = make(chan int) ChannelKillDiskClean = make(chan int) ChannelKillSubscriber = make(chan int) ChannelKillMove = make(chan int) ChannelKillConsume = make(chan int) KillChannel = 5 KillTimes = 0 MutexKill sync.Mutex ) // KillSignal 停止信号,主从节点接收到数据后准备重启 type KillSignal struct { NodeName string DropUploadData bool Restart bool } // KillService 定义要远程调用的类型和方法 type KillService struct{} // Kill 杀死自身程序,通过通道实现 方法必须满足RPC规范:函数有两个参数,第一个参数是请求,第二个是响应 func (m *KillService) Kill(args *KillSignal, reply *int) error { c_log.GlobalLogger.Info("接收到自杀信号:", *args) // 1 杀死 rosbag record 命令 ChannelKillRosRecord <- 1 // 2 杀死所有 ros 订阅者 ChannelKillSubscriber <- 1 // 3 杀死上传任任务 if args.DropUploadData == true { // 3-1 等待上传结束再杀死 ChannelKillMove <- 1 ChannelKillConsume <- 1 } else { // 3-2 直接杀死 ChannelKillMove <- 2 ChannelKillConsume <- 2 } go killDone(args.Restart) return nil } func WaitKillSelf() { killService := new(KillService) err := rpc.Register(killService) if err != nil { c_log.GlobalLogger.Error("注册rpc服务失败:", err) return } // 等待并处理远程调用请求 for { conn, err := commonConfig.KillSignalListener.Accept() if err != nil { continue } go rpc.ServeConn(conn) } } func AddKillTimes(info string) { MutexKill.Lock() switch info { case "1": ChannelKillDiskClean <- 1 close(ChannelKillRosRecord) KillTimes++ c_log.GlobalLogger.Infof("已杀死 record 打包 goroutine,当前自杀进度 %v / %v", KillTimes, KillChannel) case "2": close(ChannelKillDiskClean) KillTimes++ c_log.GlobalLogger.Infof("已杀死 bag 包数量维护 goroutine,当前自杀进度 %v / %v", KillTimes, KillChannel) case "3": close(ChannelKillSubscriber) KillTimes++ c_log.GlobalLogger.Infof("已杀死 rosnode 和ros 订阅者 goroutine,当前自杀进度 %v / %v", KillTimes, KillChannel) case "4": close(ChannelKillMove) KillTimes++ c_log.GlobalLogger.Infof("已杀死 bag 包移动 goroutine,当前自杀进度 %v / %v", KillTimes, KillChannel) case "5": close(ChannelKillConsume) KillTimes++ c_log.GlobalLogger.Infof("已杀死 bag 包消费 goroutine,当前自杀进度 %v / %v", KillTimes, KillChannel) } MutexKill.Unlock() } func killDone(restart bool) { for { time.Sleep(time.Duration(1) * time.Second) if KillChannel == KillTimes { if restart { _, err := util.ExecuteWithPath(commonConfig.LocalConfig.RestartCmd.Dir, commonConfig.LocalConfig.RestartCmd.Name, commonConfig.LocalConfig.RestartCmd.Args...) if err != nil { c_log.GlobalLogger.Info("启动新程序失败,【path】=", commonConfig.LocalConfig.RestartCmd.Dir, "【cmd】=", commonConfig.LocalConfig.RestartCmd.Name, commonConfig.LocalConfig.RestartCmd.Args, ":", err) os.Exit(-1) } c_log.GlobalLogger.Info("数据采集任务更新,正常退出当前程序。") } else { c_log.GlobalLogger.Info("数据采集任务终止,正常退出当前程序。") } os.Exit(0) } } }