func main() { runtime.GOMAXPROCS(runtime.NumCPU()) flag.Parse() if len(*configFile) == 0 { fmt.Println("must use a config file") return } cfg, err := config.ParseWorkerConfigFile(*configFile) if err != nil { fmt.Printf("parse config file error:%v\n", err.Error()) return } //when the log file size greater than 1GB, kingtask will generate a new file if len(cfg.LogPath) != 0 { sysFilePath := path.Join(cfg.LogPath, sysLogName) sysFile, err := golog.NewRotatingFileHandler(sysFilePath, MaxLogSize, 1) if err != nil { fmt.Printf("new log file error:%v\n", err.Error()) return } golog.GlobalLogger = golog.New(sysFile, golog.Lfile|golog.Ltime|golog.Llevel) } if *logLevel != "" { setLogLevel(*logLevel) } else { setLogLevel(cfg.LogLevel) } var w *worker.Worker w, err = worker.NewWorker(cfg) if err != nil { golog.Error("main", "main", err.Error(), 0) golog.GlobalLogger.Close() w.Close() return } sc := make(chan os.Signal, 1) signal.Notify(sc, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) go func() { sig := <-sc golog.Info("main", "main", "Got signal", 0, "signal", sig) golog.GlobalLogger.Close() w.Close() }() golog.Info("main", "main", "Worker start!", 0) w.Run() }
func (w *Worker) CmdRunWithTimeout(cmd *exec.Cmd, timeout time.Duration) (error, bool) { done := make(chan error) go func() { done <- cmd.Wait() }() var err error select { case <-time.After(timeout): // timeout if err = cmd.Process.Kill(); err != nil { golog.Error("worker", "CmdRunTimeout", "kill error", 0, "path", cmd.Path, "error", err.Error(), ) } golog.Info("worker", "CmdRunWithTimeout", "kill process", 0, "path", cmd.Path, "error", errors.ErrExecTimeout.Error(), ) go func() { <-done // allow goroutine to exit }() return errors.ErrExecTimeout, true case err = <-done: return err, false } }
func (w *Worker) Run() error { w.running = true for w.running { uuid, err := w.redisClient.SPop(config.RequestUuidSet).Result() //没有请求 if err == redis.Nil { time.Sleep(time.Second) continue } if err != nil { golog.Error("Worker", "run", "spop error", 0, "error", err.Error()) continue } reqKey := fmt.Sprintf("t_%s", uuid) //获取请求中所有值 request, err := w.redisClient.HMGet(reqKey, "uuid", "bin_name", "args", "start_time", "time_interval", "index", ).Result() if err != nil { golog.Error("Worker", "run", err.Error(), 0, "req_key", reqKey) continue } //key不存在 if request[0] == nil { golog.Error("Worker", "run", "Key is not exist", 0, "req_key", reqKey) continue } _, err = w.redisClient.Del(reqKey).Result() if err != nil { golog.Error("Worker", "run", "delete result failed", 0, "req_key", reqKey) } taskResult, err := w.DoTaskRequest(request) if err != nil { golog.Error("Worker", "run", "DoTaskRequest", 0, "err", err.Error(), "req_key", reqKey) } if taskResult != nil { err = w.SetTaskResult(taskResult) if err != nil { golog.Error("Worker", "run", "DoTaskRequest", 0, "err", err.Error(), "req_key", reqKey) } golog.Info("worker", "run", "do task success", 0, "req_key", reqKey, "result", taskResult.Result) } if w.cfg.Peroid != 0 { time.Sleep(time.Second * time.Duration(w.cfg.Peroid)) } } return nil }
func (b *Broker) CreateRpcTaskRequest(c *echo.Context) error { args := struct { Method string `json:"method"` URL string `json:"url"` Args string `json:"args"` //json Marshal后的字符串 StartTime int64 `json:"start_time,string"` TimeInterval string `json:"time_interval"` //空格分隔各个参数 MaxRunTime int64 `json:"max_run_time,string"` }{} err := c.Bind(&args) if err != nil { return c.JSON(http.StatusForbidden, err.Error()) } fmt.Println(args) taskRequest := new(task.TaskRequest) taskRequest.Uuid = uuid.New() if len(args.URL) == 0 { return c.JSON(http.StatusForbidden, errors.ErrInvalidArgument.Error()) } taskRequest.BinName = args.URL taskRequest.Args = args.Args taskRequest.StartTime = args.StartTime taskRequest.TimeInterval = args.TimeInterval taskRequest.Index = 0 taskRequest.MaxRunTime = args.MaxRunTime switch args.Method { case "GET": taskRequest.TaskType = task.RpcTaskGET case "POST": taskRequest.TaskType = task.RpcTaskPOST case "PUT": taskRequest.TaskType = task.RpcTaskPUT case "DELETE": taskRequest.TaskType = task.RpcTaskDELETE default: return c.JSON(http.StatusForbidden, errors.ErrInvalidArgument.Error()) } err = b.HandleRequest(taskRequest) if err != nil { return c.JSON(http.StatusForbidden, err.Error()) } golog.Info("Broker", "CreateRpcTaskRequest", "ok", 0, "uuid", taskRequest.Uuid, "bin_name", taskRequest.BinName, "args", taskRequest.Args, "start_time", taskRequest.StartTime, "time_interval", taskRequest.TimeInterval, "index", taskRequest.Index, "max_run_time", taskRequest.MaxRunTime, "task_type", taskRequest.TaskType, ) return c.JSON(http.StatusOK, taskRequest.Uuid) }
func (b *Broker) CreateScriptTaskRequest(c *echo.Context) error { args := struct { BinName string `json:"bin_name"` Args string `json:"args"` //空格分隔各个参数 StartTime int64 `json:"start_time,string"` TimeInterval string `json:"time_interval"` //空格分隔各个参数 MaxRunTime int64 `json:"max_run_time,string"` }{} err := c.Bind(&args) if err != nil { return c.JSON(http.StatusForbidden, err.Error()) } taskRequest := new(task.TaskRequest) taskRequest.Uuid = uuid.New() if len(args.BinName) == 0 { return c.JSON(http.StatusForbidden, errors.ErrInvalidArgument.Error()) } taskRequest.BinName = args.BinName taskRequest.Args = args.Args taskRequest.StartTime = args.StartTime taskRequest.TimeInterval = args.TimeInterval taskRequest.Index = 0 taskRequest.MaxRunTime = args.MaxRunTime taskRequest.TaskType = task.ScriptTask err = b.HandleRequest(taskRequest) if err != nil { return c.JSON(http.StatusForbidden, err.Error()) } golog.Info("Broker", "CreateScriptTaskRequest", "ok", 0, "uuid", taskRequest.Uuid, "bin_name", taskRequest.BinName, "args", taskRequest.Args, "start_time", taskRequest.StartTime, "time_interval", taskRequest.TimeInterval, "index", taskRequest.Index, "max_run_time", taskRequest.MaxRunTime, "task_type", taskRequest.TaskType, ) return c.JSON(http.StatusOK, taskRequest.Uuid) }