将结果存储到Play 2.2中的缓存中

时间:2013-12-28 12:13:26

标签: caching playframework-2.0 ehcache

在Play框架2.2中创建当前请求的结果非常简单。我们只输入:

Ok(views.html.default.render())

然后让它工作就足以用Action包装它,所以最终的代码看起来像:

def index = Action {
  Ok(views.html.default.render())
}

没关系。但是现在,我想将响应存储在缓存中以使其更具可伸缩性。我使用EHCache。问题是,当我将它存储到缓存中时,它会抛出

NotSerializableException: play.api.mvc.ActionBuilder$$anon$1

我试图至少缓存自己的结果,但它会抛出

ERROR net.sf.ehcache.store.disk.DiskStorageFactory Disk Write of result-key failed: 
java.io.NotSerializableException: play.api.libs.iteratee.Enumerator$$anon$18

我知道,这些值存储在缓存中,但仅存储在内存中,考虑到真正的高负载和许多不同的响应,这可能非常不足。

问题:

所以我的问题是,是否有任何方法可以完全缓存Play动作/结果,包括正确的序列化?

编辑:

我如何尝试使用缓存:我不使用Cached {},因为它的行为并不完全符合我的需要,因此我尝试以自己的方式设计它。因此,仅仅为了测试目的,我现在更详细地使用它:

Cache.set("myaction", Action {
  Ok(views.html.default.render())
})

Cache.set("myresponse", Ok(views.html.default.render()))

但这两种情况都会产生上述异常。

关于缓存:Play缓存API对我来说还不够,所以我通过另外几种方法和新的插件实现扩展了它。起初我尝试只复制默认插件并实现这些扩展但有一些问题,所以我修复了它们是here。这是插件修复。从那以后,它似乎实际上使用了EHCache(从那些例外中猜测)。

2 个答案:

答案 0 :(得分:1)

在我看来,你不是试图将结果存储在缓存中,而是操作,然后包含一个无法序列化的闭包,我想这不是你想要做的事情,我猜这是因为你是直接使用EHCache吗?

如果您使用Play缓存API,它应该可以帮助您做正确的事情。您可以在此处找到相关文档:http://www.playframework.com/documentation/2.2.x/ScalaCache

但是响应可能仍然不是可序列化的,如果你真的想要一个序列化为磁盘的缓存,你应该能够缓存模板生成的HTML,因为它基本上是一个字符串,然后重新使用它,但创建一个每个请求的新响应。

(我的直觉是,除了你有一些非常疯狂的复杂模板之外,你每次渲染模板的性能可能会比从磁盘读取它的缓存更好)

答案 1 :(得分:0)

不确定它是否适用于2.2,但根据issue我报告的

如果你直接从CacheApi的实现中调用set方法并且实现需要一个可序列化的对象,请使用@cached帮助器也使用的wrapper