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 からの 1 ミリ秒は、get が来るまでにまだ期限切れになっているはずだから?!?

put エントリの即時期限切れ (および削除!) を保証するために、Expiration をどのような値に設定できますか? AppEngine はサーバー間のクロック同期の保証を提供しないため、現在のタイムスタンプを使用するだけでは確実に機能しない可能性があることに注意してください。

これを実行したいというのは、一見すると無意味に思えますが (なぜ単に削除しないのでしょうか?)、ここで使用したいと思います: AppEngine Memcache のアトミックな 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 で割って秒に変換されます。

したがって、1 ミリ秒の有効期限を設定すると、0 秒 (1000 で割ると切り捨て) になります。

したがって、答えは次のとおりですExpiration.onDate(new Date(1000))。memcache サーバーがまだ 60 年代に生きていない限り、すぐに期限切れになるはずです... :) 試してみました。動作します。終わり...

(これらのテストは DevServer で行われました。本番サーバーでも同じように動作することを願っています。)

于 2014-05-05T18:15:37.287 に答える