Django / Python中的Celery任务最佳做法

尤瓦尔·亚当(Yuval Adam)

考虑一个需要繁重工作才能异步完成的功能。呼叫客户端可以立即获取缓存的版本,也可以获取数字被处理的响应(对客户端有效的响应)。

以下代码段是否是该模式的正确实现?

from django.core import cache
from proj.celery import app

class SomeModel(models.Model):
    # ...
    def get_crunched_numbers(self):
        cache_key = 'foo:{}'.format(self.id)
        res = cache.get(cache_key)
        if not res:
            @app.task
            def gen_crunched_numbers():
                res = do_heavy_lifting()
                cache.set(cache_key, res)
                return res
            gen_crunched_numbers.delay()
            return 'crunching... come back later'
        else:
            return res

在将所有逻辑包含在单个代码段中的同时,还有更好的替代方法来运行Celery任务吗?

编辑:如注释中所述,此代码甚至无法正常工作。因此,关于好的模式的任何建议都是必须的。

丹努拉

您的代码看起来很混乱。为什么不在类之外定义celery任务函数,并这样调用它:

from django.core import cache
from proj.celery import app

class SomeModel(models.Model):
    # ...
    def get_crunched_numbers(self):
        cache_key = 'foo:{}'.format(self.id)
        res = cache.get(cache_key)
        if not res:
            gen_crunched_numbers.delay(cache_key)
            return 'crunching... come back later'
        else:
            return res

@app.task
def gen_crunched_numbers(cache_key):
    res = do_heavy_lifting()
    cache.set(cache_key, res)
    return res

我通常也喜欢用以下命令创建任务bind=True

@app.task(bind=True)
def gen_crunched_numbers(self, cache_key):
    res = do_heavy_lifting()
    cache.set(cache_key, res)
    return res

这使我可以通过访问任务上下文self.request例如,根据是通过celery还是直接调用函数来更改行为:

@app.task(bind=True)
def gen_crunched_numbers(self, cache_key):
    res = do_heavy_lifting()
    cache.set(cache_key, res)
    if self.request.called_directly:
        return res
    else:
        return { 'result': res, 'cache': cache_key }

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章