Java中的数据存储区回调和App Engine模块

时间:2013-09-18 23:04:12

标签: google-app-engine

是否有人测试了谷歌应用引擎模块(目前处于预览状态)?

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

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

MODULE1:

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();
}

MODULE2:

@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中声明的输出...

提前致谢

1 个答案:

答案 0 :(得分:0)

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

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

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

这有一些后果:

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

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

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

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