func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transport.Stream, srv *service, sd *StreamDesc) (err error) { ss := &serverStream{ t: t, s: stream, p: &parser{s: stream}, codec: s.opts.codec, tracing: EnableTracing, } if ss.tracing { ss.traceInfo.tr = stream.Trace() ss.traceInfo.firstLine.client = false ss.traceInfo.firstLine.remoteAddr = t.RemoteAddr() if dl, ok := stream.Context().Deadline(); ok { ss.traceInfo.firstLine.deadline = dl.Sub(time.Now()) } ss.traceInfo.tr.LazyLog(&ss.traceInfo.firstLine, false) defer func() { ss.mu.Lock() if err != nil && err != io.EOF { ss.traceInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) ss.traceInfo.tr.SetError() } ss.traceInfo.tr.Finish() ss.traceInfo.tr = nil ss.mu.Unlock() }() } if appErr := sd.Handler(srv.server, ss); appErr != nil { if err, ok := appErr.(rpcError); ok { ss.statusCode = err.code ss.statusDesc = err.desc } else { ss.statusCode = convertCode(appErr) ss.statusDesc = appErr.Error() } } if ss.tracing { ss.mu.Lock() if ss.statusCode != codes.OK { ss.traceInfo.tr.LazyLog(stringer(ss.statusDesc), true) ss.traceInfo.tr.SetError() } else { ss.traceInfo.tr.LazyLog(stringer("OK"), false) } ss.mu.Unlock() } return t.WriteStatus(ss.s, ss.statusCode, ss.statusDesc) }
func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.Stream, srv *service, md *MethodDesc) (err error) { var traceInfo traceInfo if EnableTracing { traceInfo.tr = stream.Trace() defer traceInfo.tr.Finish() traceInfo.firstLine.client = false traceInfo.firstLine.remoteAddr = t.RemoteAddr() if dl, ok := stream.Context().Deadline(); ok { traceInfo.firstLine.deadline = dl.Sub(time.Now()) } traceInfo.tr.LazyLog(&traceInfo.firstLine, false) defer func() { if err != nil && err != io.EOF { traceInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) traceInfo.tr.SetError() } }() } p := &parser{s: stream} for { pf, req, err := p.recvMsg() if err == io.EOF { // The entire stream is done (for unary RPC only). return err } if err != nil { switch err := err.(type) { case transport.ConnectionError: // Nothing to do here. case transport.StreamError: if err := t.WriteStatus(stream, err.Code, err.Desc); err != nil { grpclog.Printf("grpc: Server.processUnaryRPC failed to write status: %v", err) } default: panic(fmt.Sprintf("grpc: Unexpected error (%T) from recvMsg: %v", err, err)) } return err } switch pf { case compressionNone: statusCode := codes.OK statusDesc := "" df := func(v interface{}) error { if err := s.opts.codec.Unmarshal(req, v); err != nil { return err } if traceInfo.tr != nil { traceInfo.tr.LazyLog(&payload{sent: false, msg: v}, true) } return nil } reply, appErr := md.Handler(srv.server, stream.Context(), df) if appErr != nil { if err, ok := appErr.(rpcError); ok { statusCode = err.code statusDesc = err.desc } else { statusCode = convertCode(appErr) statusDesc = appErr.Error() } if traceInfo.tr != nil && statusCode != codes.OK { traceInfo.tr.LazyLog(stringer(statusDesc), true) traceInfo.tr.SetError() } if err := t.WriteStatus(stream, statusCode, statusDesc); err != nil { grpclog.Printf("grpc: Server.processUnaryRPC failed to write status: %v", err) return err } return nil } if traceInfo.tr != nil { traceInfo.tr.LazyLog(stringer("OK"), false) } opts := &transport.Options{ Last: true, Delay: false, } if err := s.sendResponse(t, stream, reply, compressionNone, opts); err != nil { switch err := err.(type) { case transport.ConnectionError: // Nothing to do here. case transport.StreamError: statusCode = err.Code statusDesc = err.Desc default: statusCode = codes.Unknown statusDesc = err.Error() } return err } if traceInfo.tr != nil { traceInfo.tr.LazyLog(&payload{sent: true, msg: reply}, true) } return t.WriteStatus(stream, statusCode, statusDesc) default: panic(fmt.Sprintf("payload format to be supported: %d", pf)) } } }