简体   繁体   English

未来[A]与未来[Throwable \\ / A]

[英]Future[A] vs Future[Throwable \/ A]

Why do some people bother to represent failure in a scala.concurrent.Future using scala's Either or scalaz's \\/ instead of using the failed state of the Future? 为什么有些人不愿意使用scala的Either或scalaz的\\/来代表scala.concurrent.Future失败,而不是使用Future的失败状态?

How do you handle errors then and how do you chain calls on the happy path? 那你如何处理错误呢?你如何在快乐的道路上连接电话?


Update with some examples: 更新一些例子:

converting Akka's Future[A] to Future[Either[Exception,A]] 将Akka的未来[A]转换为未来[要么[例外,A]]

Scalaz Task - the missing documentation This one answers the why part, and suggests using scalaz.EitherT for chaining calls (that's for \\/ , what about Either or Try ?), but I wonder if one should ever use Future.failed , on what conditions, etc, and how to check failure. Scalaz任务 - 缺少的文档这个回答了为什么部分,并建议使用scalaz.EitherT来链接调用(这是为了\\/ ,或者是Either还是Try ?),但是我想知道是否应该使用Future.failed ,on what what条件等,以及如何检查失败。

I'm not sure if this is a widespread practice though, that's why I'm asking. 我不确定这是否是一种普遍的做法,这就是为什么我要问。 :) :)

I personally use Either inside a future when I have "failures that I can expect" and can do something to recover from them. 当我遇到“我能期待的失败”时,我个人会在未来使用Either,并且可以做些什么来从中恢复。 Especially if I need to make information about possible failures explicit to external users of API 特别是如果我需要向API的外部用户显示可能的故障信息

sealed trait UserServiceError
case object UserDbNotAvailable extends UserServiceError
case object UserNotFoung extends UserServiceError

def getUser(id: Long): Future[UserServiceError \/ User]

This code is much more explicit about what failures can happen. 此代码更明确地说明了可能发生的故障。 In some cases it can be important. 在某些情况下,它可能很重要。

The same can be achieved with Future[User] and Future.recover but in this case information about possible failures is not in type (can be in documentation) 使用Future [User]和Future.recover可以实现相同的功能,但在这种情况下,有关可能的故障的信息不在类型中(可以在文档中)

However I agree that it's very controversial design decision, because Try is already designed for failure handling. 但是我同意这是一个非常有争议的设计决定,因为Try已经设计用于故障处理。

I treat the failed state of Future the same way I treat exceptions: they're for unexpected failures that indicate either programming errors or system failures like OutOfMemoryError s. 我对待Future的失败状态的方式与对待异常的方式相同:它们用于表示程序错误或系统故障(例如OutOfMemoryError的意外故障。 As such they're not expected to be caught or handled except in a very high-level "retry the whole task" way. 因此,除非以非常高级的“重试整个任务”方式,否则不要捕获或处理它们。

Failed futures are not very typesafe (a failure is just Throwable ), and can conflate these system-level failures with a more semantic failure that can be handled in a predictable way. 失败的Future并不是非常安全的类型(失败只是Throwable ),并且可以将这些系统级失败与更语义的失败(可以通过可预测的方式处理)混为一谈。 So if I have a failure "within" my system, eg Unauthorized , then I'd rather represent that as an Either , something like Future[Unauthorized \\/ MessageData] . 因此,如果我的系统“内部”发生故障,例如Unauthorized ,那么我宁愿将其表示为Either ,例如Future[Unauthorized \\/ MessageData] Then there are three possible states: 然后有三种可能的状态:

  • Success(\\/-(data)) - success Success(\\/-(data)) - 成功
  • Success(-\\/(unauthorized)) - "expected" failure. Success(-\\/(unauthorized)) - “预期”失败。 Something that I know how to handle specificly, eg by displaying a particular message to the user or returning a particular return code. 我知道如何进行特定处理,例如通过向用户显示特定消息或返回特定返回码。 Should not set off an alert for the programmer. 不应该为程序员启动警报。
  • Failure(throwable) - unexpected, system-level failure. Failure(throwable) -系统级意外故障。 Can only be handled with a generic error page or some such. 只能使用通用错误页面或某些错误页面来处理。 Should be setting off monitoring and alerting the programmer. 应该引起监视和警告程序员。

I used to use a monad transformer to make composing the happy path easier (ie EitherT[Future, Unauthorized, MessageData] ), which works very well, though now I'm looking at a more generic approach (my scalaz-transfigure library). 我曾经使用monad转换器使编写幸福的路径变得更容易( EitherT[Future, Unauthorized, MessageData] ),效果很好,尽管现在我正在寻找一种更通用的方法(我的scalaz-transfigure库)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM