google-app-engine - 为什么我的 Google App Engine 邮件 API 调用仍然会导致 DeadlineExceededError 尽管将它们放入任务队列?

标签 google-app-engine task-queue

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

DeadlineExceededError:API 调用 mail.Send() 响应时间过长,已被取消。

有什么解决办法吗?

最佳答案

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

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

不幸的是,Mail API 没有记录在案的类比。不过,有一个变通方法,它涉及提供您自己的 make_sync_call 方法 - 这允许更宽松的截止日期 - 作为 EmailMessage.send() 的参数。要生成这样的方法,您需要深入研究用于进行 GAE RPC 调用的 Python 接口(interface)的内部结构。我发现有效的解决方案如下所示:

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 方法将遵守该截止日期:

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

如果您想了解更多关于 GAE RPC 调用幕后发生的事情,我建议阅读 Nick Johnson's blog post about it .如果您想要通过 Python 的 GAE RPC 绑定(bind)来解决类似问题,这是一个很好的起点。

关于google-app-engine - 为什么我的 Google App Engine 邮件 API 调用仍然会导致 DeadlineExceededError 尽管将它们放入任务队列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7607189/

相关文章:

python - Networkx 作为任务队列?

java - 线程池中每个线程的队列

python - GAE强制推送任务队列执行下一个任务

python - 任务队列和非幂等任务

java - 如何保护用于服务器到服务器通信的 App Engine 端点?

java - Appengine 转换 Api (java)

python - 如何修复这个 AttributeError?

php - 如何在 Google 云平台上部署我的 PHP 应用程序?

php - 从 Python/AppEngine 迁移到 PHP 的最佳框架

javascript - 如何使用 q.js Promise 处理多个异步操作