我喜欢Objectify的“只是使用ofy()”方便来获得一个Objectify实例,但我遇到了一个用例,我可以使用一些建议。
我的数据存储区的用例是,在我的过程的一部分中,我将在长时间运行的过程中编写实体。成千上万的实体。它们将分散在时间/实体组中(因此数据存储区争用对我来说并不是一个问题)。在这个长时间运行的过程中,我不需要读取数据存储区实体一次。
我知道我可以通过使用Objectify.cache(false)来创建一个不使用memecache的实例来禁用“二级”缓存。那很好。
我关心的是会话缓存。我只是稍微窥视了Objectify代码,当我们为我们遇到的实体执行“save()”时,似乎在WriteEngine.java中:
// Also stuff this in the session
session.addValue(key, obj);
所以客观化是在记忆中抓住我的物品?我想在任何可能的缓存中关闭保存实体。
答案 0 :(得分:2)
所以要明确...... @stickfigure的答案是标准Objectify的明确答案。我希望他能查看这段代码并发表评论。而且我希望Objectify将来可能有更多的缓存选项......甚至可能在实体层面!在那之前,下面是我正在使用的黑客,也许其他人会觉得有用。
那些如果你曾经使用过Objectify一段时间的人可能会记住这个服务模型的想法。您可以通过包含
来使用此OfyService
import static com.industryopenings.seeker.shared.OfyService.ofyw;
在班级的顶部。然后,您只需拨打ofyw()
,通常会拨打ofy()
。请注意...... ofyr()
和ofyw()
的混合不是我对此代码的意图。混合可能会产生奇怪的结果。特别是在交易中。
这OfyService
有两件事......
Objectify
创建的ofyw()
实例具有cache(false)
规范而不是默认cache(true)
clear()
来电OFYW_USE_COUNT_THRESHOLD
ofyw()
方法
醇>
请记住,我们没有太多能力来检查客观化会话......这里没有对象大小或对象计数逻辑。它假定您定期调用ofyw()
(不保留Objectify实例)并且只是为您定期清除会话。
import com.googlecode.objectify.*;
import com.googlecode.objectify.impl.ObjectifyImpl;
public final class OfyService {
public final static int OFYW_USE_COUNT_THRESHOLD = 10;
public static int currentReferenceCount = 0;
private static ObjectifyFactory defaultFactory = new ObjectifyFactory();
private static ObjectifyFactory noCacheFactory = new NoCacheFactory();
// This factory always returns a no-cache instance.
// BUT: end users can be foolish and turn it back on if they want... having potentially ripple effects downstream
// Best practice if you're going to use this OfyService is to never call the cache(boolean) method
private static class NoCacheFactory extends ObjectifyFactory {
@Override
public Objectify begin() {
return new ObjectifyImpl<>(this).cache(false);
}
}
// Note! We probably need to register our classes in both factories
static {
defaultFactory.register(Doc.class);
defaultFactory.register(SiteLogEntry.class);
defaultFactory.register(SiteLogRunSummary.class);
noCacheFactory.register(Doc.class);
noCacheFactory.register(SiteLogEntry.class);
noCacheFactory.register(SiteLogRunSummary.class);
}
// ofyr to get an Objectify... with the "r" to denote read / caching enabled.
public static Objectify ofyr() {
ObjectifyService.setFactory(defaultFactory);
return ObjectifyService.ofy();
}
// ofyr to get an Objectify... with the "w" to denote writing / no caching enabled.
public static Objectify ofyw(){
// This will ensure we're not using second level cache (memecache)
ObjectifyService.setFactory(noCacheFactory);
// In lieu of a true solution we're simply going to clean house every X times ofyw() is called
currentReferenceCount++;
Objectify o = ObjectifyService.ofy();
if(currentReferenceCount > OFYW_USE_COUNT_THRESHOLD){
o.clear();
currentReferenceCount = 0;
}
return o;
}
}
希望这有助于其他人。
答案 1 :(得分:1)
不幸的是,现在唯一的方法是定期拨打ofy().clear()
。我看到你在github跟踪器中添加了一个问题,这很好。