celery signature app instance 创建简单说明

celery 对于celery 实例的处理比较有意思,没有的会创建默认的,如果定义了会基于python 的threading.local 进行引用,所以我们会看到

celery 一些代码使用上比较有意思(group,chain等,不需要明确指定app 就可以进行任务的创建以及数据获取)

一个简单通过signature进行group 任务的处理

  • 示例
from celery import Celery,group,signature
app = Celery('app',backend="redis://localhost:6379/0", broker='redis://localhost:6379/0')
print("define app: ",app)

taska = app.signature('app.task_add',args=(2, 3),options={'queue': 'queue1'})
taskb = app.signature('app.task_subtract',args=(4, 5),options={'queue': 'queue2'})

group_tasks = group(taska, taskb).apply_async()
print(group_tasks.get())
  • 相似效果
from celery import Celery,group,signature
app = Celery('app',backend="redis://localhost:6379/0", broker='redis://localhost:6379/0')
print("define app: ",app)

taska = signature('app.task_add',args=(2, 3),options={'queue': 'queue1'})

print("taska app:", taska.app)
taskb = signature('app.task_subtract',args=(4, 5),options={'queue': 'queue2'})

group_tasks = group(taska, taskb).apply_async()
print(group_tasks.get())

内部处理简单说明

实际上核心还是当执行的时候,定义只是一个声明,在具体执行的时候会进行celery instance 的选择以及创建

  • group apply_async 简单处理
def apply_async(self, args=None, kwargs=None, add_to_parent=True,
                producer=None, link=None, link_error=None, **options):
    args = args if args else ()
    if link is not None:
        raise TypeError('Cannot add link to group: use a chord')
    if link_error is not None:
        raise TypeError(
            'Cannot add link to group: do that on individual tasks')
    # 此处app 是一个属性
    app = self.app
    if app.conf.task_always_eager:
        return self.apply(args, kwargs, **options)
    if not self.tasks:
        return self.freeze()

    options, group_id, root_id = self._freeze_gid(options)
    tasks = self._prepared(self.tasks, [], group_id, root_id, app)
    p = barrier()
    results = list(self._apply_tasks(tasks, producer, app, p,
                                     args=args, kwargs=kwargs, **options))
    result = self.app.GroupResult(group_id, results, ready_barrier=p)
    p.finalize()

    # - Special case of group(A.s() | group(B.s(), C.s()))
    # That is, group with single item that's a chain but the
    # last task in that chain is a group.
    #
    # We cannot actually support arbitrary GroupResults in chains,
    # but this special case we can.
    if len(result) == 1 and isinstance(result[0], GroupResult):
        result = result[0]

    parent_task = app.current_worker_task
    if add_to_parent and parent_task:
        parent_task.add_trail(result)
    return result   

app 的处理

@property
def app(self):
    app = self._app
    if app is None:
        try:
            # 为空,先尝试基于task获取
            app = self.tasks[0].app
        except LookupError:
            pass
    return app if app is not None else current_app  # 否则通过current_app

current_app 的处理(包含了_get_current_app 以及_set_current_app)

def _get_current_app():
    if default_app is None:
        #: creates the global fallback app instance.
        from celery.app.base import Celery
        set_default_app(Celery(
            'default', fixups=[], set_as_current=False,
            loader=os.environ.get('CELERY_LOADER') or 'default',
        ))
    return _tls.current_app or default_app


def _set_current_app(app):
    _tls.current_app = app

_set_current_app 的处理

实际上当我们实例化celery 的时候会使用到此方法

# 此方法有一个参数 celery的set_as_current 为true执行,默认这个参数为True
def set_current(self):
    """Make this the current app for this thread."""
    _set_current_app(self)

celery 定义

def __init__(self, main=None, loader=None, backend=None,
             amqp=None, events=None, log=None, control=None,
             set_as_current=True, tasks=None, broker=None, include=None,
             changes=None, config_source=None, fixups=None, task_cls=None,
             autofinalize=True, namespace=None, strict_typing=True,
             **kwargs):

说明

celery 一些使用有时让我们会比较迷惑,实际上是内部隐藏了比较多的东西,结合源码学习会加深对于celery 的使用

参考资料

https://docs.celeryq.dev/en/stable/userguide/canvas.html

posted on   荣锋亮  阅读(7)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
历史上的今天:
2024-03-02 Open Data Contract Standard(ODCS) data contracts 标准
2024-03-02 通过@vercel/ncc 优化node npm 项目的大小
2024-03-02 dremio jobprofile查询简单说明
2023-03-02 cube.js dremio-odbc-cubejs-driver TypeError: Do not know how to serialize a BigInt 问题
2023-03-02 基于odbc 开发一个高性能的dremio cube.js driver
2023-03-02 iframe sandbox 造成附件下载问题解决
2022-03-02 dremio 社区版目前依赖的一些闭源包

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示