为避免 DeadlineExceededExceptions,请使用多个延迟推送任务队列。使用任务队列,可以更轻松地将多个任务分解为更小的工作单元,从而防止任何单个任务超过分配给任务队列的 10 分钟阈值。
使用任务队列 API,应用程序可以在用户请求之外执行由用户请求发起的工作。如果应用程序需要执行一些后台工作,它可以使用任务队列 API 将该工作组织成小的离散单元,称为任务。该应用程序将任务添加到任务队列以稍后执行。
延迟任务队列是推送任务队列,本质上是计划任务,它们具有预定的触发时间。以下是如何创建延迟任务的简短示例:
import logging
from google.appengine.ext import deferred
def do_something_expensive(a, b, c=None):
logging.info("Fetching Twitter feeds!")
# Fetch the Twitter data here
# Somewhere else - Pass in parameters needed by the Twitter API
deferred.defer(do_something_expensive, "BobsTwitterParam1", "BobsTwitterParam2", c=True)
deferred.defer(do_something_expensive, "BobsFriendTwitterParam1", "BobsFriendTwitterParam2", c=True)
您从 Twitter 用户获取数据的过程本质上是递归的,因为您正在为追随者的追随者等获取数据,而这个任务作为一个单一的过程可能非常昂贵并且可能会超过阈值。
任务必须在原始请求的 10 分钟内完成执行并发送一个介于 200-299 之间的 HTTP 响应值。此截止日期与用户请求不同,后者有 60 秒的截止日期。如果您的任务执行接近限制,App Engine 会引发 DeadlineExceededError(来自模块 google.appengine.runtime),您可以在截止日期过去之前捕获该错误以保存您的工作或记录进度。如果任务执行失败,App Engine 会根据您可以配置的条件重试它。
但是,如果您将每个 Twitter 用户分成一个完全独立的任务,那么每个任务只运行为获取单个用户的 Twitter 结果所需的时间。这不仅更有效,而且如果在获取用户数据之一时出现问题,只有该任务会失败,而其他任务应该继续执行。
换句话说,不要尝试在单个任务中获取所有数据。
或者,如果在不太可能发生的情况下或出于任何原因,这些任务应该超过 10 分钟的阈值,请查看Backends。