Почему мои вызовы API почты Google App Engine все еще приводят к DeadlineExceededError, несмотря на то, что они помещаются в очередь задач? - PullRequest
3 голосов
/ 30 сентября 2011

У меня есть функция Python, которая добавляет очередь задач для каждого адреса электронной почты в моем списке рассылки (тысячи каждый раз, когда я отправляю их по почте).Проблема в том, что, хотя каждое письмо должно было быть отправлено через выполнение в очереди задач, я все еще получаю эту страшную ошибку:

DeadlineExceededError: The API call mail.Send() took too long to respond and was cancelled.

Любые решения?

1 Ответ

1 голос
/ 30 сентября 2011

Крайний срок наступает во время связи между вашим экземпляром GAE и сервером RPC, который обрабатывает вызов mail.Send.Это, в свою очередь, может указывать на внутренние проблемы GAE или (более вероятно) невозможность своевременной связи с SMTP-сервером.

Последний концептуально очень похож на крайний срок при вызове URLFetch.Однако можно установить пользовательский крайний срок для URLFetch, который в значительной степени облегчает эту проблему.

К сожалению, нет документированной аналогии для Mail API.Однако существует обходной путь, предусматривающий предоставление собственного метода make_sync_call - который учитывает более мягкий срок - в качестве параметра EmailMessage.send().Чтобы создать такой метод, вам нужно вникнуть во внутренний интерфейс Python, используемый для выполнения вызовов GAE RPC.Решение, которое я нахожу рабочим, выглядит следующим образом:

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, я предлагаю прочитать сообщение в блоге Ника Джонсона об этом .Это хорошая отправная точка, если вы когда-нибудь захотите пройти через привязки Python GAE RPC для решения подобных проблем.

...