Celery Prefork池下的装饰器模式:任务上下文自动注入
利用装饰器在Celery任务执行前自动注入数据库连接、日志追踪ID、权限上下文,避免在每个任务中重复样板代码,同时确保Prefork进程安全。 · 难度:入门 · +10XP
装饰器包装任务
Celery任务常需要访问Django ORM、设置日志上下文或检查用户权限。直接在每个任务开头写相同代码容易遗漏。本教程创建一组可组合的装饰器(@db_session、@trace_id、@require_permission),它们接收任务函数并返回包装后的函数。装饰器内部使用contextvars保证Prefork下的线程隔离,同时通过Celery的before_task_publish信号自动注入初始上下文。最终任务代码只需专注于业务逻辑。
# tasks/decorators.py
from contextvars import ContextVar
from functools import wraps
request_id_var = ContextVar('request_id')
def trace_id(task_func):
@wraps(task_func)
def wrapper(*args, **kwargs):
request_id = request_id_var.get(None)
if request_id is None:
request_id = kwargs.pop('_trace_id', None)
# logic
return task_func(*args, **kwargs)
return wrapper
@celery_app.task
@trace_id
@db_session
def process_order(order_id):
# clean code here
pass