github.com/profzone/eden-framework@v1.0.10/pkg/courier/transport_grpc/request.go (about) 1 package transport_grpc 2 3 import ( 4 "context" 5 "fmt" 6 "time" 7 8 "github.com/sirupsen/logrus" 9 "google.golang.org/grpc" 10 "google.golang.org/grpc/metadata" 11 "google.golang.org/grpc/status" 12 13 "github.com/profzone/eden-framework/pkg/courier" 14 "github.com/profzone/eden-framework/pkg/courier/httpx" 15 "github.com/profzone/eden-framework/pkg/courier/status_error" 16 "github.com/profzone/eden-framework/pkg/duration" 17 ) 18 19 type GRPCRequest struct { 20 RequestID string 21 BaseURL string 22 ServerName string 23 Method string 24 Timeout time.Duration 25 Req interface{} 26 Metadata courier.Metadata 27 } 28 29 func (grpcRequest *GRPCRequest) Do() (result courier.Result) { 30 result = courier.Result{} 31 d := duration.NewDuration() 32 defer func() { 33 logger := d.ToLogger().WithFields(logrus.Fields{ 34 "grpc": grpcRequest.BaseURL, 35 "service": grpcRequest.ServerName, 36 "method": grpcRequest.Method, 37 "metadata": grpcRequest.Metadata, 38 }) 39 40 if result.Err == nil { 41 logger.Infof("success") 42 } else { 43 logger.Warnf("do grpc request failed %s", result.Err) 44 } 45 }() 46 47 ctx, cancel := context.WithTimeout(context.Background(), grpcRequest.Timeout) 48 defer cancel() 49 50 conn, dialErr := grpc.DialContext(ctx, grpcRequest.BaseURL, grpc.WithInsecure(), grpc.WithCodec(&MsgPackCodec{})) 51 if dialErr != nil { 52 result.Err = status_error.RequestTimeout 53 return 54 } 55 defer conn.Close() 56 57 md := metadata.Pairs(httpx.HeaderRequestID, grpcRequest.RequestID) 58 59 stream, errForInitial := grpc.NewClientStream( 60 metadata.NewOutgoingContext(context.Background(), md), 61 &grpc.StreamDesc{ 62 StreamName: grpcRequest.Method, 63 }, conn, 64 fmt.Sprintf("/%s/%s", grpcRequest.ServerName, grpcRequest.Method), 65 ) 66 67 if errForInitial != nil { 68 result.Err = status_error.InvalidStruct.StatusError().WithDesc(errForInitial.Error()) 69 return 70 } 71 72 if errForSend := stream.SendMsg(grpcRequest.Req); errForSend != nil { 73 result.Err = status_error.RequestTimeout.StatusError().WithDesc(errForSend.Error()) 74 return 75 } 76 77 if errForClose := stream.CloseSend(); errForClose != nil { 78 result.Err = status_error.RequestTimeout.StatusError().WithDesc(errForClose.Error()) 79 return 80 } 81 82 err := stream.RecvMsg(&result.Data) 83 md, errForGetHeader := stream.Header() 84 if errForGetHeader == nil { 85 result.Meta = courier.Metadata(md) 86 } 87 88 if err != nil { 89 if s, ok := status.FromError(err); ok { 90 result.Err = status_error.ParseString(s.Message()) 91 return 92 } 93 result.Err = status_error.UnknownError 94 return 95 } 96 97 result.Unmarshal = MsgPackUnmarshal 98 return 99 }