使用 Django、celery 和 Redis 安排任务

米特威

我在 Celery 中添加了一个用于数据导出的任务。我希望当用户调用Export all按钮时,导出任务开始,前端显示django 消息,而导出在后台继续。但从我能做的事情来看,我有这个views.py

def CasesPaluExport(request):
    export_cases_palu.delay(request=request)
    messages.success(request, 'CasesPaluExport')
    return JsonResponse({"Ok": "ok"}, safe=False)

这在tasks.py

def export_cases_palu(request):
    try:
        plaintext = get_template('stock/download_case_palu.txt')
        htmly = get_template('stock/download_case_palu.html')
        d = Context({'username': request.user.username})

        subject, from_email, to = 'Download all cases palu', settings.DEFAULT_FROM_EMAIL, request.user.email
        text_content = plaintext.render(d)
        html_content = htmly.render(d)
        msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
        msg.attach_alternative(html_content, "text/html")
        msg.send()
    except:
        logging.warning("Tried to send download email to user {0}".format(request.user))

问题是,每当我调用该CasesPaluExport函数时,都会export_cases_palu.delay(request=request)在行中收到错误消息

Internal Server Error: /user/casepaluexport/
Traceback (most recent call last):
  File "/home/user/.virtualenvs/project/local/lib/python2.7/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/home/user/.virtualenvs/project/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/user/.virtualenvs/project/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/user/.virtualenvs/project/local/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/user/project/user/views.py", line 170, in CasesPaluExport
    export_cases_palu.delay(request=request)
  File "/home/user/.virtualenvs/project/local/lib/python2.7/site-packages/celery/app/task.py", line 413, in delay
    return self.apply_async(args, kwargs)
  File "/home/user/.virtualenvs/project/local/lib/python2.7/site-packages/celery/app/task.py", line 536, in apply_async
    **options
  File "/home/user/.virtualenvs/project/local/lib/python2.7/site-packages/celery/app/base.py", line 737, in send_task
    amqp.send_task_message(P, name, message, **options)
  File "/home/user/.virtualenvs/project/local/lib/python2.7/site-packages/celery/app/amqp.py", line 554, in send_task_message
    **properties
  File "/home/user/.virtualenvs/project/local/lib/python2.7/site-packages/kombu/messaging.py", line 169, in publish
    compression, headers)
  File "/home/user/.virtualenvs/project/local/lib/python2.7/site-packages/kombu/messaging.py", line 252, in _prepare
    body) = dumps(body, serializer=serializer)
  File "/home/user/.virtualenvs/project/local/lib/python2.7/site-packages/kombu/serialization.py", line 221, in dumps
    payload = encoder(data)
  File "/usr/lib/python2.7/contextlib.py", line 35, in __exit__
    self.gen.throw(type, value, traceback)
  File "/home/user/.virtualenvs/project/local/lib/python2.7/site-packages/kombu/serialization.py", line 54, in _reraise_errors
    reraise(wrapper, wrapper(exc), sys.exc_info()[2])
  File "/home/user/.virtualenvs/project/local/lib/python2.7/site-packages/kombu/serialization.py", line 50, in _reraise_errors
    yield
  File "/home/user/.virtualenvs/project/local/lib/python2.7/site-packages/kombu/serialization.py", line 221, in dumps
    payload = encoder(data)
  File "/home/user/.virtualenvs/project/local/lib/python2.7/site-packages/kombu/utils/json.py", line 72, in dumps
    **dict(default_kwargs, **kwargs))
  File "/usr/lib/python2.7/json/__init__.py", line 250, in dumps
    sort_keys=sort_keys, **kw).encode(obj)
  File "/usr/lib/python2.7/json/encoder.py", line 207, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python2.7/json/encoder.py", line 270, in iterencode
    return _iterencode(o, 0)
  File "/home/user/.virtualenvs/project/local/lib/python2.7/site-packages/kombu/utils/json.py", line 62, in default
    return super(JSONEncoder, self).default(o)
  File "/usr/lib/python2.7/json/encoder.py", line 184, in default
    raise TypeError(repr(o) + " is not JSON serializable")
EncodeError: <WSGIRequest: POST '/user/casepaluexport/'> is not JSON serializable
[20/Nov/2017 15:47:56] "POST /user/casepaluexport/ HTTP/1.1" 500 186320

这可能表明服务器仍在等待 http 响应。我该如何解决?

丹尼尔罗斯曼

该错误告诉您它无法序列化整个request以将其发送到任务。

但是您在请求中在任务本身中唯一使用的是用户对象。您应该只发送用户 ID,然后在任务中获取对象本身。

 export_cases_palu.delay(user_id=request.user.id)

...

def export_cases_palu(user_id):
    user = User.objects.get(id=user_id)
    d = Context({'username': user.username})

(此外,您不应该将整个任务包装在 try/except 中。)

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

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

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

使用 django、celery 和 redis 一一完成任务

我在使用 Celery、Redis 和 Django 时遇到问题

Django 和 Celery 任务

如何使用asyncio安排和取消任务

如何使用Django和Celery记录所有任务信息?

如何使用django和celery在特定时间启动任务

Celery/Django/Redis 相同的任务被多次执行

使用Redis从C ++触发Celery任务

使用Redis和Celery设置Django以通过Gmail发送电子邮件

使用django-background-tasks在特定时间安排任务

在Django中安排任务

如何使用Celery和Django将任务路由到不同的队列

Celery + Redis-延迟触发任务时Django阻止

Django celery redis从队列中删除特定的定期任务

Django 中带有 Redis 代理的 Celery:任务成功执行,但仍然存在太多持久性 Redis 键和连接

异步抓取并使用django celery和redis存储我的结果并存储我的正确方法是什么?

Django:如何使用 Celery 忽略任务?

Django celery:安排重复任务,但开始日期固定

Django-Celery在Windows Server上安排日常任务

在 Flask 中使用 redis 后端的 Celery 任务优先级

Celery不使用Redis处理Kubernetes中的任务

Celery + Django-使用Django消息框架进行状态和报告成功或失败的轮询任务

RabbitMQ或Redis使用Django 2.0爆炸Celery队列

使用ScheduledExecutorService安排每月任务

Laravel:使用Beanstalkd安排任务

使用MongoDB(MongoEngine)和Redis测试Django

Django-celery和RabbitMQ不执行任务

Celery在使用Django数据库执行之前撤销任务

如何使用celery在Django上设置定期任务?