我用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:不是讲英语的本地人,加上新的芹菜,如果我使用了一些错误的术语,那就太好了。
答案 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)
我对编程比较陌生,我希望这个答案可以帮助像我这样的新手。如果我弄错了,请随意进行更正。