尽管我将Google App Engine Mail API调用放入任务队列,为什么仍将导致DeadlineExceededError? [英] Why does my Google App Engine Mail API calls still result in a DeadlineExceededError despite putting them in a task queue?

查看:85
本文介绍了尽管我将Google App Engine Mail API调用放入任务队列,为什么仍将导致DeadlineExceededError?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Python函数,可为我的邮件列表中的每个电子邮件地址添加一个任务队列(每次我将其发送数千个).问题是,即使每封邮件都是通过执行在任务队列中发送的,我仍然会收到这个可怕的错误:

I have a Python function that adds a task queue for each email address in my mailing list (thousands each time I mail them). The problem is that, even though each mail was to be sent via execution in a task queue, I still get this dreaded error:

DeadlineExceededError:API调用mail.Send()花费的时间太长,因此无法响应.

有解决方案吗?

推荐答案

最后期限发生在您的GAE实例与处理 mail.Send 调用的RPC服务器之间的通信期间.反过来,这可能表明GAE内部存在问题,或者(更可能是)无法及时与SMTP服务器通信.

The deadline happens during communication between your GAE instance and the RPC server that handles the mail.Send call. This, in turn, might indicate internal problems of GAE or (more likely) failure to communicate with SMTP server in timely manner.

后者在概念上与URLFetch调用的截止日期非常相似.但是,可以为URLFetch设置自定义截止日期,从而在很大程度上缓解该问题.

The latter is conceptually very similar to deadline on URLFetch call. It is possible, however, to set a custom deadline for URLFetch which largely alleviates that problem.

不幸的是,没有关于Mail API的记录类比.但是,有一种解决方法,涉及提供您自己的 make_sync_call 方法-允许更宽限的截止期限-作为 EmailMessage.send()的参数.要产生这种方法,您需要深入研究用于进行GAE RPC调用的Python接口的内部.我发现可行的解决方案如下:

Unfortunately, there is no documented analogy for Mail API. There is workaround, though, that involves providing your own make_sync_call method - which allow for more lenient deadline - as parameter of EmailMessage.send(). To produce such a method, you need to delve into the internals of Python's interface used to make GAE RPC calls. The solution I find working looks as follows:

from google.appengine.api import apiproxy_stub_map
from google.appengine.api.apiproxy_stub_map import APIProxyStubMap

class TimeoutAPIStub( object ):
    def __init__( self, service, deadline = 25 ):
        self.service = service
        self.deadline = deadline

    def CreateRPC( self ):
        rpc = apiproxy_stub_map.CreateRPC( self.service )
        rpc.deadline = self.deadline
        return rpc

def create_MakeSyncCall( service, deadline = 25 ):
    apsm = APIProxyStubMap()
    apsm.RegisterStub( service, TimeoutAPIStub( service, deadline ) )
    return apsm.MakeSyncCall

然后您可以使用它提供您的自定义截止日期,这将由生成的 make_sync_call 方法兑现:

You can then use it to supply your custom deadline which will be honored by the resulting make_sync_call method:

msg = EmailMessage()
# ... prepare your email ...
msg.send(make_sync_call = create_MakeSyncCall('mail', deadline = 300))

如果您想进一步了解GAE RPC调用的幕后情况,建议阅读

If you want to know more about what happens under the curtains of GAE RPC calls, I suggest reading Nick Johnson's blog post about it. This is good starting point if you'd ever want to go through the Python's GAE RPC bindings in order to solve similar issues.

这篇关于尽管我将Google App Engine Mail API调用放入任务队列,为什么仍将导致DeadlineExceededError?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆