0

我使用 cron 任务在每个星期六 9:00 向我的应用程序用户发送邮件。但是如果有很多用户,这会不会有问题?如果是,我能做些什么来改进我的代码。我可以指定一个 cron 任务,例如“从 9:00 到 23:00”,以确保所有用户都能收到电子邮件吗?我听说过任务队列,但我不知道如何使用它。我真的需要吗?

编辑

我终于设法使任务队列使用此代码。

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/

如果我要编写这段代码(出于尼克详述的原因,我不会),我会做的是决定某种分片。假设您在“成员”数据库模型中有一个“收件人”字段:创建 26 个任务,其中一个将处理所有以“a”、“b”等开头的电子邮件地址。

您可能会发现该特定方案导致分布不均——也许一项任务最终完成了 50% 的工作,因为出于某种原因,您的大多数用户都有一个以“m”开头的电子邮件地址。如果发生这种情况,您可以改为基于“目标”地址的哈希进行分片。关键是要以某种方式分解您的成员并启动一个任务来处理每个块,并将块的一些标识符作为任务的参数。俗话说,编写代码和优化分片留给读者作为练习。(当然,如果您对实施有具体问题,请询问!)

于 2012-04-26T19:19:01.400 回答
0

我实际上只是有这个确切的问题。我以前从未对 stackoverflow 做出过回答,所以请善待。

我正在做的实际上是使用 cron 作业(安排在东部时间凌晨 3:30)来启动任务以进入任务队列。从那里您可以添加一个 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 回答