如何解决在递归循环中处理和共享 Monix 任务的状态
我有以下代码递归迭代并通过网络执行某些操作。当它通过网络时,我想做一些优化,其中第一个优化是避免我已经尝试过的某些元素通过网络。
例如,在下面的情况下,我调用一个 URL,提取在该 URL 中找到的 HREF,然后调用这些 URL 并报告状态。由于可能会再次获取某些 URL,对于那些失败的 URL,我想将它们添加到全局状态,以便下次遇到此 URL 时,我将避免这些网络调用。
代码如下:
def callURLWithCache(url: String): Task[HttpResult] = {
Task {
Http(url).timeout(connTimeoutMs = 1000,readTimeoutMs = 3000).asstring
}.attempt.map {
case Left(err) =>
println(s"ERR happened ----------------- $url ************************ ${err.getMessage}")
// Add to the cache
val httpResult = HttpResult(source = url,isSuccess = false,statusCode = 1000,errorMessage = Some(err.getMessage))
val returnnnn: Try[Any] = httpResultErrorCache.put(url)(httpResult)
httpResult
case Right(doc) =>
if (doc.isError) {
HttpResult(source = url,isSuccess = doc.isSuccess,statusCode = doc.code)
} else {
val hrefs = (browser.parseString(doc.body) >> elementList("a[href]") >?> attr("href"))
.distinct.flatten.filter(_.startsWith("http"))
HttpResult(source = url,statusCode = doc.code,elems = hrefs)
}
}
}
您可以在 case Left(....) 块中看到我将失败的 case 类添加到缓存中,我在此函数的封闭类上全局定义为:
val underlyingcaffeineCache: cache.Cache[String,Entry[HttpResult]] = caffeine.newBuilder().maximumSize(10000L).build[String,Entry[HttpResult]]
implicit val httpResultErrorCache: Cache[HttpResult] = caffeineCache(underlyingcaffeineCache)
这是我进行递归操作的函数:
def parseSimpleWithFilter(filter: ParserFilter): Task[Seq[HttpResult]] = {
def parseInner(depth: Int,acc: HttpResult): Task[Seq[HttpResult]] = {
import cats.implicits._
if (depth > 0) {
val batched = acc.elems.collect {
case elem if httpResultErrorCache.get(elem).toOption.exists(_.isEmpty) =>
callURLWithCache(elem).flatMap(newElems => parseInner(depth - 1,newElems))
}.sliding(30).toSeq
.map(chunk => Task.parSequence(chunk))
Task.sequence(batched).map(_.flatten).map(_.flatten)
} else Task.pure(Seq(acc))
}
callURLWithCache(filter.url).map(elem => parseInner(filter.recursionDepth,elem)).flatten
}
可以看出我正在检查我当前 elem 的 url 是否已经在缓存中,这意味着我已经尝试过但失败了,所以我想避免再次进行 HTTP 调用为它。
但结果是,httpResultErrorCache 总是空的。我不确定 Task 块是否导致了这种行为。关于如何让缓存工作的任何想法?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。