package client import ( "errors" "fmt" "github.com/ouqiang/gocron/modules/logger" "github.com/ouqiang/gocron/modules/rpc/grpcpool" pb "github.com/ouqiang/gocron/modules/rpc/proto" "golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/codes" "time" ) var ( errUnavailable = errors.New("无法连接远程服务器") ) func Exec(ip string, port int, taskReq *pb.TaskRequest) (string, error) { defer func() { if err := recover(); err != nil { logger.Error("panic#rpc/client.go:Exec#", err) } }() addr := fmt.Sprintf("%s:%d", ip, port) conn, err := grpcpool.Pool.Get(addr) if err != nil { return "", err } isConnClosed := false defer func() { if !isConnClosed { grpcpool.Pool.Put(addr, conn) } }() c := pb.NewTaskClient(conn) if taskReq.Timeout <= 0 || taskReq.Timeout > 86400 { taskReq.Timeout = 86400 } timeout := time.Duration(taskReq.Timeout) * time.Second ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() resp, err := c.Run(ctx, taskReq) if err != nil { return parseGRPCError(err, conn, &isConnClosed) } if resp.Error == "" { return resp.Output, nil } return resp.Output, errors.New(resp.Error) } func parseGRPCError(err error, conn *grpc.ClientConn, connClosed *bool) (string, error) { switch grpc.Code(err) { case codes.Unavailable, codes.Internal: conn.Close() *connClosed = true return "", errUnavailable case codes.DeadlineExceeded: return "", errors.New("执行超时, 强制结束") } return "", err }