0

cron タスクを使用して、毎週土曜日の 9:00 にアプリ ユーザーにメールを送信します。でも、利用者が多ければ問題ないのでは?そうである場合、コードを改善するために何ができますか。すべてのユーザーがメールを受信できるようにするために、「9:00 から 23:00 まで」のような cron タスクを指定できますか? タスク キューについて聞いたことがありますが、使い方がわかりません。本当に必要ですか?

編集

最終的に、このコードでタスク キューを機能させることができました。

class SendMailHandler(webapp.RequestHandler):
    def get(self):
        members = Members.all()
        for member in members:
            taskqueue.add(url='/send', params={'sender_address':sender_address,
                                                   'user_address':user_address,
                                                   'subject':subject,
                                                   'html':html})

class SendMail(webapp.RequestHandler):
    def post(self):
        sender_address = self.request.get('sender_address')
        user_address = self.request.get('user_address')
        subject = self.request.get('subject')
        html = self.request.get('html')

        mail.send_mail(sender=sender_address, to=user_address, subject=subject, body='', html=html)

application = webapp.WSGIApplication([('/sendmail', SendMailHandler),
                                  ('/send', SendMail)], debug=True)
4

2 に答える 2

4

App Engine の cron タスクは、App Engine の他のタスクと同様に、完了するまでに 10 分かかります。それ以上の時間が必要な場合は、バックエンドを使用するか、送信を複数のタスク キューに分割することができます。

編集: タスク キューのドキュメントは次のとおりです: https://developers.google.com/appengine/docs/python/taskqueue/

私がこのコードを書くつもりだった場合 (Nick が詳述した理由により、私は書きません)、ある種のシャーディングを決定することです。「members」データベース モデルに「to」フィールドがあるとします。26 個のタスクを作成し、そのうちの 1 つは「a」、「b」などで始まるすべての電子メール アドレスを処理します。

特定のスキームでは、配布が乱雑になることがあります。何らかの理由でほとんどのユーザーの電子メール アドレスが「m」で始まるため、1 つのタスクが作業の 50% を実行することになるかもしれません。これが発生した場合は、代わりに「宛先」アドレスのハッシュに基づいてシャードすることができます。ポイントは、何らかの方法でメンバーを分割し、各チャンクを処理するタスクを起動し、チャンクの識別子をタスクのパラメーターとして使用することです。コードの記述とシャーディングの最適化は、よく言われているように、読者の演習として残されています。(もちろん、実装について具体的な質問がある場合は、お尋ねください!)

于 2012-04-26T19:19:01.400 に答える
0

私は実際にこの正確な問題を抱えています。私は以前にstackoverflowへの回答をコミットしたことがないので、親切にしてください。

私が実際に行っているのは、cron ジョブ (東部標準時の午前 3 時 30 分にスケジュール) を使用してタスクを開始し、タスク que に入力することです。そこから、タスク作成の一環として ETA を追加します。これは Python の日時値を受け入れます。ここから、タスクを今すぐ実行する必要があるかどうか、またはタイムゾーンに基づいて新しい ETA を計算する必要があるかどうかを判断するロジックを実行できます。

ここに私がやっているコードのチャックがあります。このコードは、Cron ハンドラーから実行されます。次に、あなたがやっているのと同じようなメールを送信しています。注意してください、私はタイムゾーン情報を dic に保存しており、それを保存されたデータから取得している情報と比較しています。これは将来的には非常に柔軟ではないかもしれませんが、今のところ、私がする必要があることにはうまくいきます。その情報を取得する他の方法がある場合は、これを別の方法で行うことができます。

bigtimezonedic = {'America/New_York' : 0, 'America/Detroit' : 0, 'America/Kentucky/Louisville' : : 0, 'America/Kentucky/Monticello' : 0, 'America/Indiana/Indianapolis' : 0, 'America/Indiana    /Vincennes' : 0, 'America/Indiana/Winamac' : 0, 'America/Indiana/Marengo' : 0, 'America/Indiana/Petersburg' : 0, 'America/Indiana/Vevay' : 0, 'America/Chicago' : 1, 'America/Indiana/Tell_City' : 1, 'America/Indiana/Knox': 1, 'America/Menominee' : 1, 'America/North_Dakota/Center' : 1, 'America/North_Dakota/New_Salem' : 1, 'America/Denver' : 2, 'America/Boise' : 2, 'America/Shiprock' : 2, 'America/Phoenix' : 2, 'America/Los_Angeles' : 3, 'America/Anchorage' : 4, 'America/Juneau' : 4, 'America/Yakutat' : 4, 'America/Nome' : 4, 'America/Adak' : 5, 'Pacific/Honolulu' : 5}

calendar_list = calendarHTML.all()
    for calendar in calendar_list:
         if bigtimezonedic.has_key(calendar.calendarTimeZone):
             if bigtimezonedic[calendar.calendarTimeZone] == 0:
                taskqueue.add(url='/emailsender',
                        params=dict(calendaruserid=calendar.userid,
                            calendarid=calendar.calendarId))
             else:
                taskqueue.add(url='/emailsender',
                        params=dict(calendaruserid=calendar.userid,
                            calendarid=calendar.calendarId),
                     eta=datetime.datetime.now() +
                     datetime.timedelta(hours=bigtimezonedic[calendar.calendarTimeZone]))
         else:
            logging.info('There is an unsupported timezone!')
于 2012-04-27T15:40:50.247 に答える