libi / dcron

轻量分布式定时任务库 a lightweight distributed job scheduler library
MIT License
422 stars 73 forks source link

添加bash支持 #49

Closed ailose closed 1 year ago

ailose commented 1 year ago

@libi 环境变量设定支持 / 命令宏替换支持就不考虑了,不适合dcron

可以 补充一下bash命令支持


func (d *Dcron) AddCmds(jobName, cronStr string, cmds []string) (err error) 

//JobWarpper is a job warpper
type JobWarpper struct {
    ID      cron.EntryID
    Dcron   *Dcron
    Name    string
    CronStr string
    Func    func()
    Job     Job

       Type      string // command, http, rpc etc. 任务类型
        Commands []string // 要执行的shell命令
       // 用于存储分隔后的任务
    cmd     []string
}

func (job *JobWarpper) splitCmd(i int) {
    job.cmd = strings.SplitN(job.Command[i], " ", 2)
}

func (job *JobWarpper) CmdRun() {
    var cmd *exec.Cmd
    var stdOut bytes.Buffer
    var stdErr bytes.Buffer
    var cmdStr string
    for i := range job.Commands {
        job.splitCmd(i)

        // 超时控制
        c := strings.Join(job.cmd, " ")
        fmt.Println(c)
        if job.Timeout > 0 {
            ctx, cancel := context.WithTimeout(context.Background(), time.Duration(job.Timeout)*time.Second)
            defer cancel()
            cmd = exec.CommandContext(ctx, "sh", "-c", c)
        } else {
            cmd = exec.Command("sh", "-c", c)
        }

        //cmd.SysProcAttr = sysProcAttr
        cmd.Stdout = &stdOut
        cmd.Stderr = &stdErr

        if i > 0 {
            cmdStr = cmdStr + "\n" + c
        } else {
            cmdStr = c
        }
        if err := cmd.Start(); err != nil {
            // 错误处理
            break
        }

        if err := cmd.Wait(); err != nil {
            // 错误处理
            if p, _ := os.FindProcess(cmd.Process.Pid); p != nil {
                // 无法杀死任务启动的子进程
                p.Kill()
            }
            // 告警之类
            break
        }
    }
    result := "------ " + cmdStr + " ----\n" + stdOut.String() + " ----\n" + stdErr.String()

    fmt.Println(result)
}

顺便提一嘴,可以加一下系统信号监控

func (np *NodePool) monitorExit() {
    quit := make(chan os.Signal, 1)
    signal.Notify(quit, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
    <-quit

    // 一些退出前  要做的节点处理逻辑 如关闭redis 连接 通知其他节点我退出了==
}
dxyinme commented 1 year ago

感觉这样挺好的,期望可以提交一个PR,建议可以兼容windows powershell