mailgun、taskqueue、ndbを使用して重複する電子メールを送信しないようにするにはどうすればよいですか?

Yamil abugattas

taskqueue APIを使用して複数のメールを送信していますが、これはmailgunを使用した小さなグループです。私のコードは多かれ少なかれ次のようになります:

class CpMsg(ndb.Model):
    group = ndb.KeyProperty()
    sent = ndb.BooleanProperty()
    #Other properties


def send_mail(messages):
    """Sends a request to mailgun's API"""
    # Some code
    pass


class MailTask(TaskHandler):
    def post(self):
        p_key = utils.key_from_string(self.request.get('p'))
        msgs = CpMsg.query(
            CpMsg.group==p_key,
            CpMsg.sent==False).fetch(BATCH_SIZE)

        if msgs:
            send_mail(msgs)

            for msg in msgs:
                msg.sent = True

            ndb.put_multi(msgs)

            #Call the task again in COOLDOWN seconds

上記のコードは正常に機能していますが、ドキュメントによると、taskqueue APIは、タスクが少なくとも1回配信されることを保証しているため、タスクはべき等である必要があります。さて、ほとんどの場合、これは上記のコードの場合に当てはまります。これは、「sent」プロパティがFalseに等しいメッセージのみを取得するためです。問題は、祖先以外のndbクエリは結果整合性しか持たないことです。つまり、タスクが2回連続して実行されると、クエリは古い結果を返し、送信されたばかりのメッセージを含める可能性があります。

メッセージの祖先を含めることを考えましたが、送信される電子メールは数千通になるので、書き込みスループットが制限されている大規模なエンティティグループがあることを意味するのではないかと心配しています。

クエリを作成するために祖先を使用する必要がありますか?または、同じ電子メールを2回送信しないようにmailgunを構成する方法はありますか?まれに、いくつかの電子メールが複数回送信される可能性があるというリスクを受け入れる必要がありますか?

ダン・コルニレスク

結果整合性のハードルを回避するための1つの可能なアプローチは、クエリをkeys_only1つにしてから、メッセージキーを反復処理して、キールックアップ(強い整合性)によって実際のメッセージを取得し、msg.sentTrueかどうかを確認し、そのような場合はそれらのメッセージの送信をスキップすることです。これらの線に沿った何か:

    msg_keys = CpMsg.query(
        CpMsg.group==p_key,
        CpMsg.sent==False).fetch(BATCH_SIZE, keys_only=True)
    if not msg_keys:
        return

    msgs = ndb.get_multi(msg_keys)
    msgs_to_send = []

    for msg in msgs:
         if not msg.sent:
             msgs_to_send.append(msg)
    if msgs_to_send:
        send_mail(msgs_to_send)

        for msg in msgs_to_send:
            msg.sent = True

        ndb.put_multi(msgs_to_send)

またpost、(@ndb.transactional()デコレータを使用して)通話をトランザクションで行う必要があります

これは、クエリの結果整合性によって引き起こされる重複に対処する必要があります。ただし、send_mail()呼び出しはべき等ではないため、データストアの競合(またはその他の理由)によるトランザクションの再試行によって重複が発生する可能性があります。一度に1つのメッセージを送信すると(おそらくタスクキューを使用して)、その可能性を減らすことができます。GAE / P:API呼び出しによるトランザクションの安全性も参照してください。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

Related 関連記事

ホットタグ

アーカイブ