Scala 从某种模式构建类型安全的通用客户机和服务器
假设已定义以下架构:Scala 从某种模式构建类型安全的通用客户机和服务器,scala,types,generic-programming,shapeless,Scala,Types,Generic Programming,Shapeless,假设已定义以下架构: object CalculatorSchema { case class AddRequest(x: Int, y: Int) case class AddReply(sum: Int) case class SubtractRequest(x: Int, y: Int) case class SubtractReply(diff: Int) // Some code to pair off Requests with respective Repl
object CalculatorSchema {
case class AddRequest(x: Int, y: Int)
case class AddReply(sum: Int)
case class SubtractRequest(x: Int, y: Int)
case class SubtractReply(diff: Int)
// Some code to pair off Requests with respective Replies
...
}
一种可能的映射可能是:
class RR[Req, Rep]
def rr[Req, Rep] = new RR[Req, Rep]()
// within CalculatorSchema, we then define the ff:
val mapping = rr[AddRequest, AddReply] ::
rr[SubtractRequest, SubtractReply] ::
HNil // from shapeless
我希望能够以以下方式构建客户端:
val calcClient = RpcGen.createClient(CalculatorSchema)
其中,以下各项应适用:
val r1: AddReply = calcClient.process(AddRequest(1, 2)) // compiles
val r2 = calcClient.process(SomethingElse(99)) // does not compile
我们假设,为了处理请求,所有客户端都会执行以下操作:
def process[Req, Rep](req: Req): Rep = {
val serialized = serialize[Req](req)
val rawResponse = sendOverHttpAndAwaitResponse(serialized)
deserialize[Rep](rawResponse)
}
object CalculatorServer {
def process(req: AddRequest) = AddReply(req.x + req.y)
def process(req: SubtractRequest) = SubtractReply(req.x - req.y)
}
另外,我们如何定义一个接受给定模式的服务器?服务器的逻辑应该类似于:
def process[Req, Rep](req: Req): Rep = {
val serialized = serialize[Req](req)
val rawResponse = sendOverHttpAndAwaitResponse(serialized)
deserialize[Rep](rawResponse)
}
object CalculatorServer {
def process(req: AddRequest) = AddReply(req.x + req.y)
def process(req: SubtractRequest) = SubtractReply(req.x - req.y)
}
但是我们如何断言CalculatorServer
应该处理来自CalculatorSchema
的所有请求
,并为每个请求返回正确的回复
此外,我们如何定义以下内容:
RpcGen.startHttpServer(CalculatorSchema, CalculatorServer)
其中,startServer
的逻辑如下:
def startHttpServer(schema: ???, server: ???): Unit = {
Http.startServer(9090) { httpReq: HttpReq =>
val req: ??? = fromHttpReq(httpReq)
val resp: ??? server.process(req)
Ok(resp)
}
}
让你的“模式”成为一种特质。检查你的课本或课堂笔记,那里一定有很多信息。首先提出你自己的解决方案。然后,如果你有任何具体的问题,回来展示你所拥有的。我们可以帮忙。我认为这不是一个容易的问题。考虑一下,我们应该允许映射请求类型到它们各自的响应类型是完全任意的。另外,
calcClient.process
应该是多态的-回复必须是基于输入的正确类型。这在某种程度上是我先前查询的延续:我不知道怎么回事,你觉得“不容易”<代码>def foo(请求:条形):Bat是请求和响应类型之间的映射。