1

有没有人测试过谷歌应用引擎模块(目前处于预览阶段)?

文档说“有状态服务(例如 Memcache、Datastore和任务队列)由应用程序中的所有模块共享”,所以我测试了是否也是跨模块共享的数据存储回调,但我的测试似乎表明如果一个模块放置了一些东西,preput(或postput)事件只会为放置实体的模块触发。

这是预期的行为还是我错过了什么?这是代码:

模块1:

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
    Key key = KeyFactory.createKey("kind", "id");
    Entity e;
    e = new Entity(key);
    ds.put(e);
    super.doPost(req, resp);
}
@PrePut(kinds = { "kind" })
void updateTimestamp(PutContext context) {
    DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
    Key key = KeyFactory.createKey("ContatoreModulo1", "contatore");
    Entity e;
    int counter = 0;
    try {
        e = ds.get(key);
        counter = Integer.parseInt(String.valueOf(e.getProperty("count")));
        counter++;
    } catch (EntityNotFoundException e1) {
        e = new Entity(key);
    }
    e.setProperty("count", String.valueOf(counter));
    ds.put(e);
    throw new RuntimeException();
}

模块2:

@PrePut(kinds = { "kind" })
void updateTimestamp(PutContext context) {
    DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
    Key key = KeyFactory.createKey("ContatoreModulo2", "contatore");
    Entity e;
    int counter = 0;
    try {
        e = ds.get(key);
        counter = Integer.parseInt(String.valueOf(e.getProperty("count")));
        counter++;
    } catch (EntityNotFoundException e1) {
        e = new Entity(key);
    }
    e.setProperty("count", String.valueOf(counter));
    ds.put(e);
    throw new RuntimeException();
}

简单地说,在 MODULE1 中,我放置了一个类型为“kind”的实体,然后在两个模块中,我尝试捕获该实体的 preput 回调,但我看到只有在 MODULE1 中声明的 preput 被调用...

提前致谢

4

1 回答 1

0

模块是独立的实例:运行不同的代码,但有状态的服务是相同的。基本上,GAE 启动运行不同模块代码但使用相同数据存储的单独服务器实例。

您运行的代码在一个服务器实例上执行,并且在您的程序中,您只能控制该实例上的程序流(除非您通过 Url fetch 显式调用另一个实例)。

另请注意,当您有大量流量时,GAE 将启动一个模块的多个服务器实例来处理该流量。

这有一些后果:

  1. 如果您在一个实例上运行一些代码,这不会神奇地调用另一个实例上的代码,无论它是否是同一个模块。您的 PrePut 代码仅在您调用 put() 的实例上被调用。

  2. 当流量很大时,会运行多个模块实例。同样,您的 PrePut 代码仅在您调用 put() 的实例上被调用,而不是在所有其他实例上。

  3. 如果您使用静态变量来存储一些数据,则这些数据将仅在此特定服务器实例上可见,而在其他实例上不可见。

  4. 在实例之间共享数据的唯一方法是有状态服务:如果您希望在实例之间和请求之间共享数据,则将其存储到数据存储区、内存缓存等。

于 2013-09-19T06:35:30.727 回答