App Engine 任务未在定义的目标中执行

App engine tasks are not executed in defined target

我正在尝试重构我的一些网站代码使用模块,但无论我尝试什么,我似乎都无法让推送任务在我想要的地方执行。

这块app的基本结构是这样的...

  1. 用户将相当大且复杂的 XML 文件上传到默认模块上的处理程序
  2. 处理程序将文件放入 GCS 并为文件创建数据存储条目
  3. 模型有一个 _post_put_hook 创建两个任务队列作业,对这个 XML 文件做一些处理。

我希望这两个任务队列作业在大于 F1 的实例中执行,因为我已经遇到 128MB 的软内存限制,并且我希望作业执行得更快一些。

所以我创建了一个 dispatch.yaml 文件(我仍然不太确定是否需要这个文件),就像这样...

application: myapp
dispatch:
- url: "*/tasks/.*"
  module: tasks

还有像这样的tasks.yaml...

application: myapp
module: tasks
version: 1
runtime: python27
api_version: 1
threadsafe: true

instance_class: F2

handlers:
  - url: /.*
  script: tasks.app
  login: admin

libraries:
- name: lxml
  version: "2.3"
- name: ssl
  version: "latest"

最后 post_put_hook 对作业进行排队是这样的...

def _post_put_hook(self, future):
    if self.identification is None:
        taskqueue.add(url='/tasks/extraction', params={'key': self.key.id()}, target="tasks", name="extractor-%s" % self.key.id())
        taskqueue.add(url='/tasks/indexer', params={'key': self.key.id()}, target="tasks", name="indexer-%s" % self.key.id()))

我的理解是,因为我在 taskqueue() 调用中指定了一个目标,它应该使用该模块,但它没有。我尝试过使用和不使用将 dispatch.yaml 文件部署到 App Engine,这似乎对任务执行的位置没有影响。 App Engine 开发控制台似乎承认有一个任务模块,因为它提供了一个选项来过滤我的日志和实例列表。

我应该补充一点,我通过 CLI 部署了该应用程序,确保同时指定了我的 app.yaml 和 tasks.yaml(这是我在尝试部署它时遇到的问题)。

尝试改变

- url: "*/tasks/.*"

- url: "*/tasks/*"

好的,我找到问题所在了。

我以为当使用 dispatch.yaml 时,"sub" 模块(我的 'tasks' 模块)安装在相应模块的基础 url 上( '/*').我是通过查看此处提供的示例 https://github.com/GoogleCloudPlatform/appengine-modules-helloworld-python 看到的

得出这种信念的
- url: "*/mobile/*"
  module: mobile-frontend

在dispatch.yaml

handlers:
- url: /.*
  script: printenv.APP

在mobile_frontend.yaml

和 printenv.py 像这样安装应用程序...

APP = webapp2.WSGIApplication([
    ('/.*', MainHandler)
], debug=True)

我仍然不太确定上面的代码是如何工作的,因为为了让我的代码工作,我必须进行上面 Dave 提到的调整并且...

把我的tasks.yaml改成

handlers:
- url: /tasks/.*
  script: tasks.app
  login: admin

并更改 tasks.py 中的路线,使其看起来像...

ROUTES = (webapp2.Route('/tasks/extraction', ExtractionWorker),
          webapp2.Route('/tasks/indexer', IndexingWorker))

以前他们看起来像

ROUTES = (webapp2.Route('/extraction', ExtractionWorker),
          webapp2.Route('/indexer', IndexingWorker))