演员的尝试总是不好的做法吗?
Is try catch in actors always bad practice?
我知道 actor 中的异常处理通常应该使用监督策略来完成。但这对所有情况都有效吗?
示例
- 有一个演员是某种数据库。
- 有几个源 actor 可以将数据添加到数据库 actor。
- 这些演员的亲子关系未知。
- 要将数据添加到数据库 actor,源 actor 必须在数据库 actor 注册。
- 如果未注册的源参与者试图将数据添加到数据库,则会引发异常。
如果我严格按照 akka actors 的错误处理策略,监督 actor 将不得不处理这种情况。
我更愿意在数据库 actor 中捕获异常并向源 actor 发送一条消息,表明出现了问题。然后源演员可以做出反应(注册到数据库并重试)。
这是一个好习惯吗?还是整个演员设置错误?如果首选监管策略,应该如何实施?
捕获异常并在您认为合适时将它们作为响应是非常好的。我建议使用 Scala 的 Try,如:
Try(dangerousOperation()) match {
case Success(res) => sender() ! res
case Failure(ex) => sender() ! UnableToStoreThingy("reasons...", ex)
}
或者类似的东西(你也可以try.failed.map { ex => doThings(ex) }
),取决于你的风格偏好。
我知道 actor 中的异常处理通常应该使用监督策略来完成。但这对所有情况都有效吗?
示例
- 有一个演员是某种数据库。
- 有几个源 actor 可以将数据添加到数据库 actor。
- 这些演员的亲子关系未知。
- 要将数据添加到数据库 actor,源 actor 必须在数据库 actor 注册。
- 如果未注册的源参与者试图将数据添加到数据库,则会引发异常。
如果我严格按照 akka actors 的错误处理策略,监督 actor 将不得不处理这种情况。
我更愿意在数据库 actor 中捕获异常并向源 actor 发送一条消息,表明出现了问题。然后源演员可以做出反应(注册到数据库并重试)。
这是一个好习惯吗?还是整个演员设置错误?如果首选监管策略,应该如何实施?
捕获异常并在您认为合适时将它们作为响应是非常好的。我建议使用 Scala 的 Try,如:
Try(dangerousOperation()) match {
case Success(res) => sender() ! res
case Failure(ex) => sender() ! UnableToStoreThingy("reasons...", ex)
}
或者类似的东西(你也可以try.failed.map { ex => doThings(ex) }
),取决于你的风格偏好。