1

我期待以下 AppEngine 代码:

MemcacheService memcache = MemcacheServiceFactory.getMemcacheService();
memcache.put("Foo", "Bar", Expiration.onDate(new Date(1)));
System.out.println(memcache.get("Foo"));
System.out.println(memcache.put("Foo", "Baz", null, SetPolicy.ADD_ONLY_IF_NOT_PRESENT));

产生以下输出:

null
true

即,通过在将条目放入缓存时将过期日期设置为 1970 年,我希望它会立即被删除并可供重用。

相反,我得到:

Bar
false

即条目仍然存在。

现在,奇怪的是,如果我将代码更改为Expiration.onDate(new Date())(不带1),即在执行 put 操作之前将到期时间设置为正确,我得到预期的“null,true”。

Memcache 是否以某种方式将过去太远的到期日期解释为相对于现在而不是绝对日期???但即使这样也不符合结果,因为从 put 开始的 1ms 应该在 get 到来时仍然过期?!?

我可以将 Expiration 设置为什么值,以保证 put 条目立即到期(并删除!)?请记住,仅使用当前时间戳可能无法可靠地工作,因为 AppEngine 不提供跨服务器的任何时钟同步保证!

我知道乍一看想要这样做听起来很荒谬(为什么不直接删除它?),但我想在这里使用它:AppEngine Memcache atomic get-and-delete(“结论”上方的句子)。

4

1 回答 1

4

哇!这很模糊,但我想通了:

查看AsyncMemcacheServiceImpl.java 中 doPut() 方法的源代码,第 505 行内容如下:

itemBuilder.setExpirationTime(expires == null ? 0 : expires.getSecondsValue());

并且Expiration.getSecondsValue()包含以下行:

return (int) (getMillisecondsValue() / 1000);

换句话说:过期值为“0”相当于没有过期(同null),过期时间除以 1000 转换为秒。

所以,如果我设置了 1ms 的过期时间,它会变成 0 秒(除以 1000 时向下舍入),这相当于没有过期......

所以,答案是:Expiration.onDate(new Date(1000))应该立即过期,除非 memcache 服务器仍然生活在 60 年代...... :) 试过了。作品。完毕...

(这些测试是在 DevServer 上完成的。我希望生产服务器的行为也一样。)

于 2014-05-05T18:15:37.287 回答