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  }