【问题标题】:Fail Ask Request on Typed Actor instead wrap with TryFail Ask Request on Typed Actor 改为使用 Try
【发布时间】:2022-01-23 00:00:15
【问题描述】:

例子

 import akka.actor.typed.scaladsl.AskPattern._
      object MyActor {
        sealed trait Command
        case class MyCommand(replyTo: ActorRef[Try[String]]) extends Command

        def apply(): Behaviors.Receive[Command] = {
          val failureMessage = util.Failure(new RuntimeException("Timeout"))
          Behaviors.receiveMessage {
            case MyCommand(replyTo) => replyTo ! failureMessage
              Behaviors.same
          }
        }
      }

      val worker = testKit.spawn(MyActor())

      // Act
      val res = worker.ask[Try[String]](me => MyActor.MyCommand(replyTo = me))

      // Assert
      println(Await.result(res, Duration.Inf)) // Return Failure(java.lang.RuntimeException: Timeout)
      // But i want to do:
      intercept[RuntimeException] {
        Await.result(res, Duration.Inf)
      }
      // and on success i want to return instead of Success[T] as T
    }

请注意,我使用Try 包装结果,以便返回SuccessFailure。问题是我不想这样做,我想在ask 请求中使整个Future 失败。

有可能吗?

【问题讨论】:

  • 删除了我的答案,因为我不确定它是否仍然适用于 akka typed,但您应该能够回复 Status.Failure 以导致 ask未来会失败。
  • @ZviMints 通常最好用akka-typed 标记使用类型化 API 的问题。
  • @Dylan Status.Failure 不能直接与 Akka Typed 一起使用

标签: scala akka akka-typed


【解决方案1】:

如果询问响应将是成功响应还是失败响应,在 Akka Typed 中,最好通过使用 askWithStatus 并调整协议以使用 StatusReply 来完成:

import akka.pattern.StatusReply

object MyActor {
  sealed trait Command
  case class MyCommand(replyTo: ActorRef[StatusReply[String]]) extends Command

  // can also wrap a Throwable, but it's generally advised to wrap a string
  val failure = StatusReply.Error("Timeout")

  def apply(): Behavior[Command] =
    Behaviors.receiveMessage {
      case MyCommand(replyTo) =>
        replyTo ! failure
        Behaviors.same
    }
}

然后,执行询问:

val res: Future[String] = worker.askWithStatus[String](MyActor.MyCommand(_))

res 将:

  • 如果被问到的演员回复了StatusReply.Success(string),请填写string
  • 如果被询问的演员回复StatusReply.Error(errorString),则以StatusReply.ErrorMessage(errorString) 失败
  • 如果被询问的演员回复StatusReply.Error(x: Throwable),则以x 失败
  • 如果在收到响应之前达到超时,则通常会失败,正常的ask 会失败

至于为什么建议包装 String 错误消息,这是因为通常情况下,请求演员做某事的代码不应该对演员的内部结构有足够的了解,因为异常的任何部分超出异常消息和(也许)异常的类型是有意义的。如果您不愿意向 Web 或 API 使用者公开该细节(例如堆栈跟踪),您可能不应该在您的询问响应中公开它。如果你在餐厅点菜,厨房里的厨师把你的食物放在地上的锅掉了,你需要服务员(你的厨房 API)回来告诉你“厨师把你的食物掉在地上了吗? ” 还是让服务员或经理过来说“抱歉,您的订单会延迟,这里有一杯饮料(或礼券之类的)”?

【讨论】:

    猜你喜欢
    • 2021-06-23
    • 2019-12-19
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 2014-12-20
    • 1970-01-01
    • 2013-03-07
    • 1970-01-01
    相关资源
    最近更新 更多