我有一个很耗时的芹菜任务,结果很明显。我想在结果可用后立即执行本地回调(或任何回调)。
我的期望是,我可以异步调用生成数据的函数,然后在该函数返回结果时执行回调。就本演示而言,我想通过调用诸如log.info
之类的琐碎函数来证明它可以工作-但在现实生活中,我可能想做一些更复杂的事情,例如将数据传递到另一个将存储结果的函数中
有一种简单的方法可以做到吗?运行脚本时,出现错误,提示我的任务无法序列化。如果我用celery任务代替了正常功能,我会得到几乎相同的错误。
stoneid_1 | File "/usr/local/lib/python3.6/site-packages/kombu/utils/json.py", line 59, in default
stoneid_1 | return super(JSONEncoder, self).default(o)
stoneid_1 | File "/usr/local/lib/python3.6/json/encoder.py", line 180, in default
stoneid_1 | o.__class__.__name__)
stoneid_1 | kombu.exceptions.EncodeError: Object of type 'log_some_information' is not JSON serializable
这是我的整个剧本:
import random
import time
import logging
import socket
from collections import namedtuple
log: logging.Logger = logging.getLogger()
from stoneid.celery.celery import app
TimeConsumingResult = namedtuple("TimeConsumingResult", ["word", "hostname"])
@app.task()
def time_consuming_thing()->TimeConsumingResult:
delay:float = random.randrange(0,3)
time.sleep(delay)
items = ["zip", "zap", "zop"]
return TimeConsumingResult(random.choice(items), socket.gethostname())
@app.task()
def log_some_information(info:TimeConsumingResult)->None:
log.info("Message: %s, host: %s", info.word, info.hostname)
def main():
while True:
time.sleep(10)
log.info("About to schedule a task:")
time_consuming_thing.apply_async(link=log_some_information)
if __name__ == "__main__":
logging.basicConfig()
logging.getLogger("").setLevel(logging.INFO)
main()
答案 0 :(得分:0)
您需要使用the signature()
method when adding a link
。 signature
方法可以缩写为s
。因此,在上面的代码中,使用以下代码:
df main():
while True:
time.sleep(10)
log.info("About to schedule a task:")
time_consuming_thing.apply_async(link=log_some_information.signature())