如何正确使用spray.io LruCache

How to properly use spray.io LruCache

我是一个没有经验的 spray/scala 开发人员,我正在尝试正确使用 spray.io LruCache。我正在尝试实现一些非常简单的事情。我有一个 kafka 消费者,当它从它的主题中读取一些东西时,我希望它把它读取的值放到缓存中。 然后在我想读取这个值的路由之一中,该值是字符串类型,我现在有如下所示:

object MyCache {

  val cache: Cache[String] = LruCache(
    maxCapacity      = 10000,
    initialCapacity  = 100,
    timeToLive       = Duration.Inf,
    timeToIdle       = Duration(24, TimeUnit.HOURS)
   )
}

为了将某些内容放入缓存,我使用以下代码:

def message() = Future { new String(singleMessage.message()) }
MyCache.cache(key, message)

然后在其中一个路由中我试图从缓存中获取一些东西:

val res = MyCache.cache.get(keyHash)

问题是 res 的类型是 Option[Future[String]],在这种情况下很难访问真实值。有人可以告诉我如何简化我的代码以使其更好和更具可读性吗? 提前致谢。

不要试图从 Future 中获取值。而是在 Future 上调用 map 以安排在 Future 完成时对值完成工作,然后使用该结果(它本身就是一个 Future)完成请求。它应该看起来像这样:

path("foo") {
  complete(MyCache.cache.get(keyHash) map (optMsg => ...))
}

此外,如果 singleMessage.message 不执行 I/O 或以其他方式阻止,那么就不要像你这样创建 Future

Future { new String(singleMessage.message) }

这样操作效率会更高:

Future.successful(new String(singleMessage.message))

后者只是创建一个已经完成的 Future,绕过使用 ExecutionContext 来评估函数。

如果 singleMessage.message 做 I/O,那么理想情况下你会 I/O 使用一些库(比如 Spray 客户端,如果它是一个 HTTP 请求)returns 一个 Future(而不是使用 Future { ... } 创建另一个将阻塞的线程)。