从某个模式构建类型安全的通用客户端和服务器

时间:2016-04-02 00:48:45

标签: 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 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)
}

但我们如何断言CalculatorServer应处理Request中的所有CalculatorSchema并为每个Reply返回正确的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) } } 的逻辑遵循:

public class ImagePanel extends JPanel {
    private Image image;

    public ImagePanel(Image image) {
        this.image = image;
        // setSize(image.getWidth(null), image.getHeight(null));
    }

    @Override
    public Dimension getPreferredSize() {
        if (image != null) {
            int w = image.getWidth();
            int h = image.getHeight();
            return new Dimension(w, h);
        } else {
            return super.getPreferredSize();
        }
    }

    @Override   // this should be protected, not public
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (image != null) {
            g.drawImage(image, 0, 0, null);
        }
    }
}

0 个答案:

没有答案