如何最佳发送gearman worker的失败作业输出?

4 投票
1 回答
1568 浏览
提问于 2025-04-17 11:03
#!/usr/bin/env python
import sys
import json
import gearman
from fabric import *
from fabric.api import *
from gearman import GearmanWorker


#
# Run the ssh task
#
def exe_job(worker, job):
    d = json.loads(job.data)
    env.host_string = d['host'] 
    cmd = d['command']
    retries = int(d['retries'])
    output = ""

    # Run the fabric command. Do not abort on exit
    # Run job for the given number of retries
    tmp_retries = retries;
    while retries > 0:
        with settings(warn_only=True):
            result = run(cmd)
            output = output + str(result)

        if result.failed:
            if retries == 1:
                job.send_fail()
                break
            else:
                next
        else:
            break

        retries = retries - 1

    return output


#
# Main function
#
def main():
    gm_worker = gearman.GearmanWorker(['localhost:4730'])
    gm_worker.register_task('exe_job',exe_job) 
    gm_worker.work()


if __name__ == '__main__':
    main()

在我的代码中,我想根据用户指定的重试次数来重试一个gearman任务(这个任务会运行一个fabric命令)。每次尝试时,我都会记录并保存输出。在最后一次重试时,如果这个任务失败了,我想把输出返回给客户端。

现在发生的问题是,job.send_fail()这个命令直接中断了,不会执行到“返回输出”的那条命令,因此无法把失败的命令输出返回。

有没有更好的方法可以让任务失败,同时在退出或失败时把数据返回给客户端,而不让工作进程崩溃呢?

1 个回答

3

在Gearman中,send_fail()这个函数不需要任何参数,它的作用就是告诉工作服务器这个工作在这个工作者上失败了,这样服务器就可以选择重试或者做其他处理。

如果你是同步执行你的程序,比较好的做法是在客户端处理“是否重试”的逻辑。

如果你是异步执行程序,我觉得可以使用“sendException”函数。(在我电脑上安装的Python Gearman模块中,它叫send_job_exception()。)这个函数可以接收一些异常数据,帮助你传递客户端的信息。

最后,你可以简单地这样做:(不过你的Gearman客户端会收到一个GEARMAN_SUCCESS的返回码!)

#some codes
while retries > 0:
    with settings(warn_only=True):
        result = run(cmd)
        output = output + str(result)

    if result.failed:
        if retries == 1:
            #job.send_fail()
            output = "FAILED_JOB" + "some_return_str"
            break
        else:
            next
    else:
        break

    retries = retries - 1

return output

这个链接也会对你有帮助。

撰写回答