简体   繁体   English

Scala Akka 流程 output 处理

[英]Scala Akka Flow output dealing with an Either

I am facing a problem using akka http and web socket.我在使用 akka http 和 web 插座时遇到问题。 I have a function through my code that is returning me the following type:我有一个 function 通过我的代码返回以下类型:

Flow[String, Either[RuntimeException, T], Any]

And from that type I have to exit with the following type:从该类型中,我必须使用以下类型退出:

Either[Unit, Flow[String, T, Any]]

Can everyone tell me how to answer Unit in case the the out part of the flow is Left(RuntimeException) and T when it's right handed.每个人都可以告诉我如何回答 Unit 以防流的输出部分是 Left(RuntimeException) 和 T 当它是右手时。

Thanks in advance for your help在此先感谢您的帮助

The issue is probably that:问题大概是:

  • Tapir expects that error to return to the user is Either[Unit, Flow[String, T, Ant]] (error algebra is not provided - Unit - so it expects that no error information will be returned to the user) Tapir 期望返回给用户的错误是Either[Unit, Flow[String, T, Ant]] (没有提供错误代数 - Unit - 所以它希望不会向用户返回错误信息)
  • OPs business logic provides Flow working with Either[RuntimeException, T] OPs 业务逻辑提供Flow使用Either[RuntimeException, T]
  • if there are some errors during websocket processing, their result can be stored in T (so T has to be internally something like Either or similar ADT)如果在 websocket 处理过程中出现一些错误,它们的结果可以存储在T中(因此T必须在内部类似于 Either 或类似的 ADT)

So endpoint either never fails on connection, or on failure shows no information to the user (since Left T = Unit).因此,端点要么在连接时永远不会失败,要么在失败时不会向用户显示任何信息(因为 Left T = Unit)。 Once connected it can just return errors as websocket responses in the form of T .一旦连接,它就可以返回错误,因为 websocket 以T的形式响应。

In such case whole flow could just be wrapped in Right(flow) and one obstacle is worked out.在这种情况下,整个流程可以只包含在Right(flow)中,并且解决了一个障碍。

Then RuntimeException can be converted to T and the second obstacle would be defeated.然后可以将RuntimeException转换为T并且第二个障碍将被击败。

def handleRequest(input: Input): Either[
  Unit, // Left(()) is failure but without any error information for users
  Flow[String, Either[RuntimeException, T], Any] // Right(flow) on success
] = ...

// implementation depends on T and is only possible if T can somehow store
// either success and failure result
val mapError: RuntimeException => T = ...

def tapirLogic(input: Input): Either[Unit, Flow[String, T, ]] = for {
  // if we should go Left on request handling this is the moment
  businessLogic <- handleRequest(input)
  // turns Either[RuntimeExeption, T] to T
  flow = businessLogic.map((_.fold(mapError, identity)))
} yield flow

What if T isn't able to store failures?如果T不能存储失败怎么办? What if it cannot be encoded eg as something like:如果它不能被编码,例如:

{ "success": "success response" }
{ "failure": "failure response" }

or similar?或类似的?

In such case your API definition is not prepared for encoding error messages that you would have to sent to your users on RuntimeException result within your business logic definition.在这种情况下,您的 API 定义未准备好对您必须在业务逻辑定义中的RuntimeException结果上发送给用户的错误消息进行编码。 Maybe you don't want to send anything in such case - then you could use some Flow operator which eg flatMapConcat single value on Right and empty Flow on Left.也许你不想在这种情况下发送任何东西——那么你可以使用一些Flow运算符,例如在 Right 上的flatMapConcat单个值和在 Left 上的空 Flow。 But if you want to be able to return some message to the user, then Tapir has to know how to encode it, and so T has to somehow encode it.但是,如果你希望能够向用户返回一些消息,那么 Tapir 必须知道如何对其进行编码,因此T必须以某种方式对其进行编码。 Maybe you need two different T s: encoding only success in original flow and encoding both T and RuntimeException messages in flow transformed for Tapir.也许您需要两个不同的T :仅在原始流中编码成功,并在为 Tapir 转换的流中同时编码TRuntimeException消息。 Here types tell you what to do to make your implementation correct.这里的类型告诉你如何做才能使你的实现正确。

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

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