Python 暂停芹菜任务

Python 暂停芹菜任务,python,flask,celery,Python,Flask,Celery,我正在尝试根据用户按钮单击暂停芹菜任务 我所做的是: 当用户点击按钮时;我发布了一个AJAX请求,将芹菜任务状态更新为“暂停” 然后,;我的策略是;当我开始一项任务到芹菜;它运行一个for循环。 每个for循环;我读取我的数据库“状态”,看看它是否设置为暂停:如果设置为暂停;我想让它休眠60秒,或者一直休眠到用户点击恢复按钮;同样的想法 这是我的代码: r = redis.StrictRedis(host='localhost', port=6379, db=0) @celery.task(

我正在尝试根据用户按钮单击暂停芹菜任务

我所做的是:

当用户点击按钮时;我发布了一个AJAX请求,将芹菜任务状态更新为“暂停”

然后,;我的策略是;当我开始一项任务到芹菜;它运行一个for循环。 每个for循环;我读取我的数据库“状态”,看看它是否设置为暂停:如果设置为暂停;我想让它休眠60秒,或者一直休眠到用户点击恢复按钮;同样的想法

这是我的代码:

r  = redis.StrictRedis(host='localhost', port=6379, db=0)

@celery.task(bind=True)
def runTask(self, arr)

   for items in arr:
      current_task_id = self.request.id
      item = r.get('celery-task-meta-'+current_task_id)
      load_as_json = json.loads(item)
      if "PAUSE" in load_as_json['status']:
        sleep(50) 




@app.route('/start')
def start_task()
   runTask.apply_async(args=[arr])
   return 'task started running
以下是我的pause API端点的外观:

@app.route('/stop/<task_id>')
def updateTaskState():
  task_id = request.cookie.get('task_id')
  loadAsJson = json.loads(r.get('celery-task-meta-'+str(task_id)))
  loadAsJson['status'] = 'PAUSE'
  loadAsJson.update(loadAsJson)
  dump_as_json = json.dumps(loadAsJson)
  updated_state = r.set('celery-task-meta-'+last_key, dump_as_json)
  return 'updated state';

面对同样的问题和没有好的答案,我提出了您可能喜欢的解决方案,它不依赖于您使用的消息队列(也称为Redis或RabbitMQ)。对我来说,关键是芹菜.app.task.task类中的update_state方法将task_id作为可选参数。在我的例子中,我通过多个工作节点运行长时间运行的文件复制和校验和任务,有时用户希望暂停一个正在运行的任务,以降低对存储的性能要求,从而允许其他任务先完成。我还运行了一个无状态的Flask REST API来启动后端任务并检索正在运行的任务的状态,因此我需要一种方法来调用API来暂停和恢复任务

下面是我的测试函数,它可以通过监视自己的状态来接收暂停自己的“消息”:

celery.task(bind=True)
def long_test(self, i):
    print('long test starting with delay of ' + str(i) + 'seconds on each loop')
    print('task_id =' + str(self.request.id))
    self.update_state(state='PROCESSING')
    count = 0
    while True:
        task = celery.AsyncResult(self.request.id)
        while task.state == 'PAUSING' or task.state == 'PAUSED':
            if task.state == 'PAUSING':
                self.update_state(state='PAUSED')
            time.sleep(i)
        if task.state == 'RESUME':
            self.update_state(state='PROCESSING')
        print('long test loop ' + str(count) + ' ' + str(task.state))
        count += 1
        time.sleep(i)
然后,为了暂停或恢复,我可以执行以下操作:

>>> from project.celeryworker.tasks import long_test
>>> from project import create_app, make_celery
>>> flaskapp = create_app()
>>> celery = make_celery(flaskapp)
>>> from celery.app.task import Task
>>> long_test.apply_async(kwargs={'i': 5})
<AsyncResult: bf19d50f-cf04-47f0-a069-6545fb253887>
>>> Task.update_state(self=celery, task_id='bf19d50f-cf04-47f0-a069-6545fb253887', state='PAUSING')
>>> celery.AsyncResult('bf19d50f-cf04-47f0-a069-6545fb253887').state
'PAUSED'
>>> Task.update_state(self=celery, task_id='bf19d50f-cf04-47f0-a069-6545fb253887', state='RESUME')
>>> celery.AsyncResult('bf19d50f-cf04-47f0-a069-6545fb253887').state
'PROCESSING'
>>> Task.update_state(self=celery, task_id='bf19d50f-cf04-47f0-a069-6545fb253887', state='PAUSING')
>>> celery.AsyncResult('bf19d50f-cf04-47f0-a069-6545fb253887').state
'PAUSED'
>>来自project.celeryworker.tasks导入长测试
>>>从项目导入创建应用程序,制作芹菜
>>>flaskapp=创建应用程序()
>>>芹菜=制作芹菜(烧瓶)
>>>从芹菜.app.task导入任务
>>>long_test.apply_async(kwargs={'i':5})
>>>任务。更新状态(self=芹菜,任务id='bf19d50f-cf04-47f0-a069-6545fb253887',状态='暂停〕
>>>芹菜。异步结果('bf19d50f-cf04-47f0-a069-6545fb253887')。状态
“暂停”
>>>任务。更新状态(self=芹菜,任务id='bf19d50f-cf04-47f0-a069-6545fb253887',状态='RESUME')
>>>芹菜。异步结果('bf19d50f-cf04-47f0-a069-6545fb253887')。状态
“处理”
>>>任务。更新状态(self=芹菜,任务id='bf19d50f-cf04-47f0-a069-6545fb253887',状态='暂停〕
>>>芹菜。异步结果('bf19d50f-cf04-47f0-a069-6545fb253887')。状态
“暂停”

你能帮我写代码吗?我试图实现你的方法,但我犯了很多错误。需要帮助
>>> from project.celeryworker.tasks import long_test
>>> from project import create_app, make_celery
>>> flaskapp = create_app()
>>> celery = make_celery(flaskapp)
>>> from celery.app.task import Task
>>> long_test.apply_async(kwargs={'i': 5})
<AsyncResult: bf19d50f-cf04-47f0-a069-6545fb253887>
>>> Task.update_state(self=celery, task_id='bf19d50f-cf04-47f0-a069-6545fb253887', state='PAUSING')
>>> celery.AsyncResult('bf19d50f-cf04-47f0-a069-6545fb253887').state
'PAUSED'
>>> Task.update_state(self=celery, task_id='bf19d50f-cf04-47f0-a069-6545fb253887', state='RESUME')
>>> celery.AsyncResult('bf19d50f-cf04-47f0-a069-6545fb253887').state
'PROCESSING'
>>> Task.update_state(self=celery, task_id='bf19d50f-cf04-47f0-a069-6545fb253887', state='PAUSING')
>>> celery.AsyncResult('bf19d50f-cf04-47f0-a069-6545fb253887').state
'PAUSED'