Django/Python中的芹菜任务最佳实践

2024-09-28 10:08:07 发布

您现在位置:Python中文网/ 问答频道 /正文

考虑一个需要异步完成一些重任务的函数。调用客户端可以立即接收缓存的版本,也可以接收正在处理数字的响应(对客户端来说是有效的响应)。在

下面的代码片段是这个模式的良好实现吗?在

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

在一段代码中包含所有逻辑的同时,有没有更好的替代方法来运行像这样的Cerry任务?在

编辑:如注释中所述,此代码甚至不起作用。因此,任何关于一个好的模式的建议都是非常感谢的。在


Tags: key代码fromimportselfapp客户端cache
1条回答
网友
1楼 · 发布于 2024-09-28 10:08:07

你的代码看起来很混乱。为什么不在类之外定义celery task函数并将其命名为:

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创建任务:

^{pr2}$

这使我可以通过self.request访问{a1}。例如,要根据函数是通过芹菜调用还是直接调用来更改行为,请执行以下操作:

@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 }

相关问题 更多 >

    热门问题