1

Celery (および rabbitmq) を使用して、Flask メールと非同期でメールを送信しようとしています。最初に、フラスコのrender_templateでセロリを壊すという問題がありました-Flask -Mailはセロリを壊します(セロリタスクは引き続き正常に実行されますが、メールは送信されませんでした)。その問題を修正しようとしているときに (まだ修正されていません!)、別の問題に遭遇しました。ねじロックによる酸洗エラーです。セロリタスクの呼び出し方法を変更したときに(遅延からapply_asyncに)問題が発生したことに気付きました。それ以来、変更を元に戻そうとしましたが、まだエラーを取り除くことができません。問題のいずれかに関するヘルプは非常に高く評価されます。

トレースバック:

File "/Users/.../python2.7/site-packages/celery/app/amqp.py",          line 250, in publish_task
    **kwargs
File "/Users/.../lib/python2.7/site-packages/kombu/messaging.py", line 157, in publish
compression, headers)
File "/Users/.../lib/python2.7/site-packages/kombu/messaging.py", line 233, in _prepare
    body) = encode(body, serializer=serializer)
File "/Users/.../lib/python2.7/site-packages/kombu/serialization.py", line 170, in encode
    payload = encoder(data)
File "/Users/.../lib/python2.7/site-packages/kombu/serialization.py", line 356, in dumps
    return dumper(obj, protocol=pickle_protocol)
PicklingError: Can't pickle <type 'thread.lock'>: attribute lookup thread.lock failed

タスク.py

from __future__ import absolute_import
from flask import render_template
from flask.ext.mail import Message
from celery import Celery

celery = Celery('tasks', 
            broker = 'amqp://tester:testing@localhost:5672/test_host')

@celery.task(name = "send_async_email")
def send_auth_email(app, nickname, email):
    with app.test_request_context("/"):
        recipients = []
        recipients.append(email)
        subject = render_template("subject.txt")
        msg = Message(subject, recipients = recipients)
        msg.html = render_template("test.html", name = nickname)
        app.mail.send(msg)   

テストケースでは、次のように呼び出します。

send_auth_email.delay(test_app, nick, email)

参考までに: セロリを使用しない場合 (つまり、同期)、API は完全に正常に動作します。前もって感謝します!

4

1 に答える 1

1

send_auth_email.delay(test_app, nick, email)すべての関数引数を呼び出すと、タスク キューに送信されます。そうするために、セロリはそれらをピクルスにします。

簡単な答えtest_appは、フラスコのアプリケーションであり、魔法を使用し、ピクルスにすることはできません。ピクルス化できるものとできないものの詳細については、ドキュメントを参照してください。

1つの解決策は、必要なすべての引数を渡して(あなたの場合、これは名前だけのようです)、で再インスタンス化test_appすることsend_auth_emailです.

于 2013-10-24T13:47:53.673 に答える