Skip to content

Server Side Request Serving Precedures in GRPC

This page is next to the client side details, Request Sending Precedures in GRPC Client Side. There are more details in it, which means this page will much more brief than previous one. Still, I focus on the core logic, ignoring like interceptors.

Files generated by protoc

The protoc generates the two type of files, one is _pb and the other is _grpc. Checking with the documents:

Protocol buffers provide a language-neutral, platform-neutral, extensible mechanism for serializing structured data in a forward-compatible and backward-compatible way. It’s like JSON, except it's smaller and faster, and it generates native language bindings.

The pb file is what mentioned here, it helps us to serialize the structed data(and deserialize), and grpc provides a default implementation of codec with name proto.

However, the protoc actually cannot generate code for _grpc, it requires the help of a special protocol buffer compiler plugin.

The generated code helps to call the grpc library instead of doing directly by users, eg, client side Invoke the rpc , server registers the implementation and handlers inject for grpc to use.

func (c *greeterClient) SayHello(ctx context.Context, in *HelloRequest,
opts ...grpc.CallOption) (*HelloReply, error) {
    out := new(HelloReply)
    err := c.cc.Invoke(ctx, "/helloworld.Greeter/SayHello", in, out, opts...)
    return out, nil
}

func RegisterGreeterServer(s grpc.ServiceRegistrar, srv GreeterServer) {
    s.RegisterService(&Greeter_ServiceDesc, srv)
}

func _Greeter_SayHello_Handler(srv interface{},
ctx context.Context, dec func(interface{}) error,
interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
    in := new(HelloRequest)
    if err := dec(in); err != nil {
        return nil, err
    }
    if interceptor == nil {
        return srv.(GreeterServer).SayHello(ctx, in)
    }
    info := &grpc.UnaryServerInfo{
        Server:     srv,
        FullMethod: "/helloworld.Greeter/SayHello",
    }
    handler := func(ctx context.Context, req interface{}) (interface{}, error) {
        return srv.(GreeterServer).SayHello(ctx, req.(*HelloRequest))
    }
    return interceptor(ctx, in, info, handler)
}

Serving requests

After checking the protobuf, let’s look at the server side diagram about serving requests. The mainly stages are:

  • register the implementation to the grpc server.
  • serve incoming requests
  • construct http2 connection from tcp accept.
  • get a stream(stand a rpc in transport layer) and handle
  • get service name, method name and so on from the stream.
  • get the method handler(call the implementation registered before running by generated _grpc file)
  • construct decoder, decompressor and function to unmarshal raw to pb struct.
  • call handler and pass the function mention above to handle the data.
  • get result and send response.

  • Diagram of how server calls implementation https://kroki.io/plantuml/svg/eNp9VMtu3DAMvOsreGraIrsL9GgUQQ75g35AQMu0LVSvUnSD_H0p2W7XbtE9WAbF4QyH9D4XQZYlePMwi-TS3W7ZY6yRq03hVujHQtHSZXA4MQZjcJEUl9ATG9PAlydoZweZkyQLE0ViFCowcbaAcYDcw-g8FROTELCbZjE1AGUJAfndXOA19x3YFAVdLCCz3gkvVgpgnxZpkQEFa2qrOyaGQvyTuDOf4Zu-OUsvVCzMWCCQzGmAiIGaglkfnvgRSOz1qoAtAE4JoHwnT9rXXVGQBBa9b8RM6MGnyVlDWqx2cW6-HRBUPYxLtOJSPKdMJMolNoN3RapL5wyrRFIFg5ogqMZDGqF260L2FEjt-VflHbc6vjZgJk5LVulTJeNTBSXY81blX4867_z8uA90-LTlamol6qB36sapcHX7Dm2apN-IIompMes9DKTj9uVOjNrbEH8ANQ5vTuY2iYN7h0S0NqvwkVPYM1futTN1KLQFUxZpZfQ91inXxf-yZfyNqGbscl0c00qw3m5bdtRRAfrpZKZSdJuqHQPZNJz11i15oUdgfLs8uagjGlE5-new-cNA2_jaCtaHTlBX4bQGh4ItdV_rZthK0ST8D1jqTqvcnGKhNgH9Peup_wK_AGjld1s=

Conclusion

After learning how client does, seems the server side is not complex. However, to be honest, I ignore many other features in grpc, which are also important.

The core process sometimes not complex, but when it supports multiple features, the complexites expand largely. I think next page, I could learn some features in grpc, but I don’t think it’s worth to be written down as it’s easy to be a copy-paste work from the document to my blog, without help.

I guess to check some deficits of grpc might help to understand better.