【问题标题】:Is calling a Future method parameter "by-name" necessary?是否需要“按名称”调用 Future 方法参数?
【发布时间】:2017-03-22 06:35:42
【问题描述】:

我有类似以下的内容,用于在 Redis 中为使用 http4s、Argonaut 和 Slick 的 Scala 应用程序缓存 JSON 响应,并想确认它是否按照我的预期工作。思路是,如果没有找到 Redis key,则调用给定的 fallback 方法从原始源(MySQL)获取数据并将其缓存以供将来请求,否则跳过 MySQL:

/** Get from MySQL */
def getThingsFromDatabase(matchingId: Int): Future[Seq[Thing]] = {
  println("getThingsFromDatabase")
  val query = things.filter(_.fieldId === matchingId)
  db.run(query.result)
}

/** Get from Redis, else MySQL via `fallback` */
def getThingsFromRedisOrDatabase(key: String,
                                 fallback: Future[Seq[Thing]]):
                                 Future[argonaut.Json] = {
  val stored = redis.get(key)
  stored match {
    // Data exists, return from redis
    case Some(s) => {
      Parse.parse(s) match {          // convert string to Json
        case Right(r) => Future { r } // Json => Future[argonaut.Json]
        case Left(l) => println(l)    // error
      }
    }
    // Data does not exist, get from database and store
    case None() => {
      val data = fallback.map(_.toList.asJson)
      data map { redis.set(key, _) }
      data // Future[argonaut.Json]
    }
  }
}

// GET /things/12
Ok(getThingsFromRedisOrDatabase("things:12", getThingsFromDatabase(12)))

这可行,但是上面的代码将始终打印“getThingsFromDatabase”,无论 Redis 中是否有数据,因为 getThingsFromDatabase(12) 在作为参数调用时会执行。原始数据库似乎没有像预期的那样被 Redis 中的数据击中(如果它关闭,则不会出现错误)。我认为这是因为fallback Future 没有在这种情况下使用,因此即使执行了该方法也没有完成。

如果将fallback: Future[Seq[Thing]] 更改为按名称调用(即fallback: => Future[Seq[Thing]]),则“getThingsFromDatabase”仅在缓存为空时第一次打印,正如预期的那样,因为fallback 仅在None() 条件而不作为参数执行。

虽然后者是预期的功能,但如果 getThingsFromDatabase 方法中没有 println如果 Redis 有所需的数据,两者似乎都满足了不去 MySQL 的需求,即使前者执行了方法,也没有真正完成 Future。

【问题讨论】:

    标签: scala future


    【解决方案1】:

    会有显着的差异。如所写,db.run() 将被调用,数据库将执行查询;结果可能会被丢弃,但通常服务器会完成所有工作。

    如果things 是一个大的、未索引的表,或者如果经常调用此代码,那么是的,您可能会看到不必要的调用导致性能显着下降。此示例是按名称调用有用性的典型代表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-26
      相关资源
      最近更新 更多