[英]Scala: Cats, OptionT[Future, T] and ApplicativeError
[英]Cats OptionT future not completing
我遇到一个我的未来(与OptionT捆绑在一起)未完成的问题。
当我显式地等待没有OptionT的结果时,我可以看到正确的输出(请参阅Some(2,2)下面的日志)。 但是在我的理解中,我们从没有看到“ Ids:”日志。 在Await OptionT println中,我们永远看不到输出。
显然,如果没有Duration.Inf,则期货超时。
这里的功能是,如果提供的ID的品牌和国家/地区不存在,我们应该失败。 如果它们存在,我们可以继续在它们之间创建链接。
def save(brandId: Int, countryId: Int): Future[Option[Int]] = {
val now = DateTime.now(DateTimeZone.UTC)
println(s"Await: ${Await.result(getIds(brandId, countryId), Duration.Inf)}")
println(s"Await OptionT: ${Await.result(OptionT(getIds(brandId, countryId)).map(identity).value, Duration.Inf)}")
for {
ids <- OptionT(getIds(brandId, countryId))
_ = logger.info(s"Ids: $ids")
brand = BrandCountry(None, ids._2, ids._1, now, "admin", now, "admin")
_ = logger.info(s"Brand: $brand")
insertStmt = BrandCountrys.returning(BrandCountrys.map(_.id)) += brand
_ = logger.info(s"Executing SQL:\n${insertStmt.statements.mkString(";\n")}")
result <- OptionT.liftF(db.run(insertStmt))
} yield result
}.value
private def getIds(brandId: Int, countryId: Int) = {
val ids = for {
bId <- Brands.filter(_.id === brandId).map(_.id)
cId <- Countries.filter(_.id === countryId).map(_.id)
} yield (bId, cId)
logger.info(s"Executing SQL:\n${ids.result.statements.mkString(";\n")}")
db.run(ids.result.headOption)
}
此处的日志输出是
[error] c.d.d.v.d.BrandCountrysDao - Executing SQL:
select x2."id", x3."id" from "configurations_v2"."brands" x2, "configurations_v2"."countries" x3 where (x2."id" = 2) and (x3."id" = 2)
Await: Some((2,2))
[error] c.d.d.v.d.BrandCountrysDao - Executing SQL:
select x2."id", x3."id" from "configurations_v2"."brands" x2, "configurations_v2"."countries" x3 where (x2."id" = 2) and (x3."id" = 2)
然后它会永远等待(Duration.Inf)
这里的问题与Cats或OptionT无关,而与scalatest提供的默认ExecutionContext相关,后者正在执行代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.