微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Monix 并行任务的错误处理使用 parMap

如何解决Monix 并行任务的错误处理使用 parMap

我正在尝试使用 monix 来并行化某些操作,然后执行错误处理

假设我正在尝试解析和验证这样的几个对象

def parseAndValidateX(x: X) Task[X]

def parseAndValidateY(y: Y): Task[Y]

这里的 X 和 Y 是我定义的一些类型。

在这方法中的每一个都会评估一些标准并返回一个任务。如果评估失败,我有一些形式的代码

Task.raiseerror(new CustomException("X is invalid because certain reasons a,b,c"))

我对 Y 有类似的任务加薪。

Task.raiseerror(new CustomException("Y is invalid because certain reasons a',b',c'"))

现在我有这种类型

case class Combined(x: X,y: Y)

我定义了这个

private def parseAndValidateCombined(x: X,y: Y): Task[Combined] = {
  val xTask = parseAndValidateX(x)
  val yTask = parseAndValidateY(y)
     
  Task.parMap2(xTask,yTask) {
    (xEval,yEval) => SecretData(xEval,yTask)
  }
}

这应该允许我并行运行验证,并且我确实得到了响应。

不过我也想要这种行为

如果两个任务都失败,我想返回这样的错误

Task.raiseerror(new CustomException("X is invalid because certain reasons a,c and "Y is invalid because certain reasons a',c'"))

我似乎无法做到这一点。根据两个任务中的哪一个失败,我只能在 parMap2 输出的 onRecover 方法上获得两个失败之一。

如果两者都失败,我只会收到任务 X 的错误

我是否有可能以完全异步的方式使用 Monix 完成我正在做的事情(例如,也许可以使用其他方法将任务组合在一起)?或者我是否必须阻止 exec,单独获取错误并重新组合值?

解决方法

仅使用 parMap2 不可能完成您想做的事情。 documentation 说:

如果其中一个任务失败,那么所有其他任务都会得到 取消,最终结果是失败。

但是,有可能实现希望您希望暴露错误,而不是隐藏在 monadic 处理之后。这可以通过 materialize 方法实现。

因此,例如,您可以将方法实现为:

private def parseAndValidateCombined[X,Y](x: X,y: Y): Task[Combined] = {
  val xTask = parseAndValidate(x).materialize // turn on Task[Try[X]]
  val yTask = parseAndValidate(y).materialize // turn on Task[Try[Y]]
     
  Task.parMap2(xTask,yTask) {
    case (Success(xEval),Success(yEval)) => Success(SecretData(xEval,yEval))
    case (Failure(_),Failure(_)) => Failure[Combined](new CustomException(....))
    case (Failure(left),_) => Failure[Combined](left)
    case (_,Failure(right)) => Failure[Combined](right)
  }.dematerialize // turn to Task[Combined]
}

希望能帮到你 :)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。