如何获得芹菜任务id

时间:2017-05-18 15:17:24

标签: python-3.x celery

我用celery beat设定了一个周期性的任务。任务运行,我可以在控制台中看到结果。 我想要一个python脚本来重新收集任务抛出的结果。

我可以这样做:

#client.py
from cfg_celery import app
task_id = '337fef7e-68a6-47b3-a16f-1015be50b0bc'
try:
    x = app.AsyncResult(id)
    print(x.get())
except:
    print('some error')

无论如何,正如你所看到的,对于这个测试我必须复制在芹菜节拍控制台上抛出的task_id(可以这么说)并在我的脚本中硬编码。显然这不会在实际生产中起作用。

我在celery配置文件中设置了task_id

#cfg_celery.py
app = Celery('celery_config',
        broker='redis://localhost:6379/0',
        include=['taskos'],
        backend = 'redis'
        )
app.conf.beat_schedule = {
    'something': {
        'task': 'tasks.add',
        'schedule': 10.0,
        'args': (16, 54),
        'options' : {'task_id':"my_custom_id"},
    }
}

这样我可以这样读:

#client.py
from cfg_celery import app
task_id = 'my_custom_id'
try:
    x = app.AsyncResult(id)
    print(x.get())
except:
    print('some error')

这种方法的问题在于我丢失了之前的结果(在调用client.py之前)。

有什么方法可以在芹菜后端读取task_id的列表吗? 如果我有多个周期性任务,我可以从每个周期性任务中获取task_id的列表吗? 我可以使用app.tasks.key()来完成此操作吗?

pd:不是讲英语的本地人,加上新的芹菜,如果我使用了一些错误的术语,那就太好了。

1 个答案:

答案 0 :(得分:0)

行。我不确定是否有人回答这个因为很难或因为我的问题太愚蠢了。 无论如何,我想要做的是从另一个python进程获得我的'芹菜击败'任务的结果。 在同一个过程中,没有问题我可以访问任务ID,从那里一切都很容易。但是从其他过程中我找不到检索已完成任务列表的方法。

我尝试了python-RQ(这很好)但是当我看到使用RQ我无法做到这一点时,我才明白我必须手动使用redis存储功能。所以我得到了我想要的东西,这样做:

。使用'bind = True'可以从任务函数中进行检查。 。一旦我得到了函数的结果,我就把它写在redis的列表中(我做了一些技巧来限制这个列表的大小) 。现在我可以从一个独立的进程连接到同一个redis服务器并检索存储在这样的列表中的结果。

我的档案最终是这样的:

cfg_celery.py:这里我定义了调用任务的方式。

#cfg_celery.py
from celery import Celery

appo = Celery('celery_config',
        broker='redis://localhost:6379/0',
        include=['taskos'],
        backend = 'redis'
        )

'''
urlea se decoro como periodic_task. no hay necesidad de darla de alta aqi.
pero como add necesita args, la doy de alta manualmente p pasarselos
'''
appo.conf.beat_schedule = {
    'q_loco': {
        'task': 'taskos.add',
        'schedule': 10.0,
        'args': (16, 54),
        # 'options' : {'task_id':"lcura"},
    }
}

taskos.py:这些是任务。

#taskos.py
from cfg_celery import appo
from celery.decorators import periodic_task
from redis import Redis

from datetime import timedelta
import requests, time

rds = Redis()

@appo.task(bind=True)
def add(self,a, b):
    #result of operation. very dummy.
    result = a + b

    #storing in redis
    r= (self.request.id,time.time(),result)
    rds.lpush('my_results',r)

    # for this test i want to have at most 5 results stored in redis
    long = rds.llen('my_results')
    while long > 5:
        x = rds.rpop('my_results')
        print('popping out',x)
        long = rds.llen('my_results')
        time.sleep(1)
    return a + b


@periodic_task(run_every=20)
def urlea(url='https://www.fullstackpython.com/'):
    inicio = time.time()
    R = dict()
    try:
        resp = requests.get(url)
        R['vato'] = url+" = " + str(resp.status_code*10)
        R['num palabras'] = len(resp.text.split())
    except:
        R['vato'] = None
        R['num palabras'] = 0        
    print('u {} : {}'.format(url,time.time()-inicio))
    time.sleep(0.8) # truco pq se vea mas claramente la dif.
    return R

consumer.py:可以获得结果的独立流程。

#consumer.py
from redis import Redis
nombre_lista = 'my_results'

rds = Redis()

tamaño = rds.llen(nombre_lista)
ultimos_resultados = list()
for i in range(tamaño):
    ultimos_resultados.append(rds.rpop(nombre_lista))

print(ultimos_resultados)

我对编程比较陌生,我希望这个答案可以帮助像我这样的新手。如果我弄错了,请随意进行更正。