mirror of
https://github.com/openfaas/faasd.git
synced 2025-06-19 20:46:40 +00:00
Migrate to containerd 1.54
Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
This commit is contained in:
committed by
Alex Ellis
parent
4c9c66812a
commit
2ae8b31ac0
262
vendor/google.golang.org/grpc/rpc_util.go
generated
vendored
262
vendor/google.golang.org/grpc/rpc_util.go
generated
vendored
@ -27,7 +27,6 @@ import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@ -155,7 +154,6 @@ func (d *gzipDecompressor) Type() string {
|
||||
type callInfo struct {
|
||||
compressorType string
|
||||
failFast bool
|
||||
stream ClientStream
|
||||
maxReceiveMessageSize *int
|
||||
maxSendMessageSize *int
|
||||
creds credentials.PerRPCCredentials
|
||||
@ -180,7 +178,7 @@ type CallOption interface {
|
||||
|
||||
// after is called after the call has completed. after cannot return an
|
||||
// error, so any failures should be reported via output parameters.
|
||||
after(*callInfo)
|
||||
after(*callInfo, *csAttempt)
|
||||
}
|
||||
|
||||
// EmptyCallOption does not alter the Call configuration.
|
||||
@ -188,8 +186,8 @@ type CallOption interface {
|
||||
// by interceptors.
|
||||
type EmptyCallOption struct{}
|
||||
|
||||
func (EmptyCallOption) before(*callInfo) error { return nil }
|
||||
func (EmptyCallOption) after(*callInfo) {}
|
||||
func (EmptyCallOption) before(*callInfo) error { return nil }
|
||||
func (EmptyCallOption) after(*callInfo, *csAttempt) {}
|
||||
|
||||
// Header returns a CallOptions that retrieves the header metadata
|
||||
// for a unary RPC.
|
||||
@ -199,16 +197,18 @@ func Header(md *metadata.MD) CallOption {
|
||||
|
||||
// HeaderCallOption is a CallOption for collecting response header metadata.
|
||||
// The metadata field will be populated *after* the RPC completes.
|
||||
// This is an EXPERIMENTAL API.
|
||||
//
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This type is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
type HeaderCallOption struct {
|
||||
HeaderAddr *metadata.MD
|
||||
}
|
||||
|
||||
func (o HeaderCallOption) before(c *callInfo) error { return nil }
|
||||
func (o HeaderCallOption) after(c *callInfo) {
|
||||
if c.stream != nil {
|
||||
*o.HeaderAddr, _ = c.stream.Header()
|
||||
}
|
||||
func (o HeaderCallOption) after(c *callInfo, attempt *csAttempt) {
|
||||
*o.HeaderAddr, _ = attempt.s.Header()
|
||||
}
|
||||
|
||||
// Trailer returns a CallOptions that retrieves the trailer metadata
|
||||
@ -219,16 +219,18 @@ func Trailer(md *metadata.MD) CallOption {
|
||||
|
||||
// TrailerCallOption is a CallOption for collecting response trailer metadata.
|
||||
// The metadata field will be populated *after* the RPC completes.
|
||||
// This is an EXPERIMENTAL API.
|
||||
//
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This type is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
type TrailerCallOption struct {
|
||||
TrailerAddr *metadata.MD
|
||||
}
|
||||
|
||||
func (o TrailerCallOption) before(c *callInfo) error { return nil }
|
||||
func (o TrailerCallOption) after(c *callInfo) {
|
||||
if c.stream != nil {
|
||||
*o.TrailerAddr = c.stream.Trailer()
|
||||
}
|
||||
func (o TrailerCallOption) after(c *callInfo, attempt *csAttempt) {
|
||||
*o.TrailerAddr = attempt.s.Trailer()
|
||||
}
|
||||
|
||||
// Peer returns a CallOption that retrieves peer information for a unary RPC.
|
||||
@ -239,17 +241,19 @@ func Peer(p *peer.Peer) CallOption {
|
||||
|
||||
// PeerCallOption is a CallOption for collecting the identity of the remote
|
||||
// peer. The peer field will be populated *after* the RPC completes.
|
||||
// This is an EXPERIMENTAL API.
|
||||
//
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This type is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
type PeerCallOption struct {
|
||||
PeerAddr *peer.Peer
|
||||
}
|
||||
|
||||
func (o PeerCallOption) before(c *callInfo) error { return nil }
|
||||
func (o PeerCallOption) after(c *callInfo) {
|
||||
if c.stream != nil {
|
||||
if x, ok := peer.FromContext(c.stream.Context()); ok {
|
||||
*o.PeerAddr = *x
|
||||
}
|
||||
func (o PeerCallOption) after(c *callInfo, attempt *csAttempt) {
|
||||
if x, ok := peer.FromContext(attempt.s.Context()); ok {
|
||||
*o.PeerAddr = *x
|
||||
}
|
||||
}
|
||||
|
||||
@ -276,7 +280,11 @@ func FailFast(failFast bool) CallOption {
|
||||
|
||||
// FailFastCallOption is a CallOption for indicating whether an RPC should fail
|
||||
// fast or not.
|
||||
// This is an EXPERIMENTAL API.
|
||||
//
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This type is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
type FailFastCallOption struct {
|
||||
FailFast bool
|
||||
}
|
||||
@ -285,16 +293,21 @@ func (o FailFastCallOption) before(c *callInfo) error {
|
||||
c.failFast = o.FailFast
|
||||
return nil
|
||||
}
|
||||
func (o FailFastCallOption) after(c *callInfo) {}
|
||||
func (o FailFastCallOption) after(c *callInfo, attempt *csAttempt) {}
|
||||
|
||||
// MaxCallRecvMsgSize returns a CallOption which sets the maximum message size the client can receive.
|
||||
func MaxCallRecvMsgSize(s int) CallOption {
|
||||
return MaxRecvMsgSizeCallOption{MaxRecvMsgSize: s}
|
||||
// MaxCallRecvMsgSize returns a CallOption which sets the maximum message size
|
||||
// in bytes the client can receive.
|
||||
func MaxCallRecvMsgSize(bytes int) CallOption {
|
||||
return MaxRecvMsgSizeCallOption{MaxRecvMsgSize: bytes}
|
||||
}
|
||||
|
||||
// MaxRecvMsgSizeCallOption is a CallOption that indicates the maximum message
|
||||
// size the client can receive.
|
||||
// This is an EXPERIMENTAL API.
|
||||
// size in bytes the client can receive.
|
||||
//
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This type is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
type MaxRecvMsgSizeCallOption struct {
|
||||
MaxRecvMsgSize int
|
||||
}
|
||||
@ -303,16 +316,21 @@ func (o MaxRecvMsgSizeCallOption) before(c *callInfo) error {
|
||||
c.maxReceiveMessageSize = &o.MaxRecvMsgSize
|
||||
return nil
|
||||
}
|
||||
func (o MaxRecvMsgSizeCallOption) after(c *callInfo) {}
|
||||
func (o MaxRecvMsgSizeCallOption) after(c *callInfo, attempt *csAttempt) {}
|
||||
|
||||
// MaxCallSendMsgSize returns a CallOption which sets the maximum message size the client can send.
|
||||
func MaxCallSendMsgSize(s int) CallOption {
|
||||
return MaxSendMsgSizeCallOption{MaxSendMsgSize: s}
|
||||
// MaxCallSendMsgSize returns a CallOption which sets the maximum message size
|
||||
// in bytes the client can send.
|
||||
func MaxCallSendMsgSize(bytes int) CallOption {
|
||||
return MaxSendMsgSizeCallOption{MaxSendMsgSize: bytes}
|
||||
}
|
||||
|
||||
// MaxSendMsgSizeCallOption is a CallOption that indicates the maximum message
|
||||
// size the client can send.
|
||||
// This is an EXPERIMENTAL API.
|
||||
// size in bytes the client can send.
|
||||
//
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This type is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
type MaxSendMsgSizeCallOption struct {
|
||||
MaxSendMsgSize int
|
||||
}
|
||||
@ -321,7 +339,7 @@ func (o MaxSendMsgSizeCallOption) before(c *callInfo) error {
|
||||
c.maxSendMessageSize = &o.MaxSendMsgSize
|
||||
return nil
|
||||
}
|
||||
func (o MaxSendMsgSizeCallOption) after(c *callInfo) {}
|
||||
func (o MaxSendMsgSizeCallOption) after(c *callInfo, attempt *csAttempt) {}
|
||||
|
||||
// PerRPCCredentials returns a CallOption that sets credentials.PerRPCCredentials
|
||||
// for a call.
|
||||
@ -331,7 +349,11 @@ func PerRPCCredentials(creds credentials.PerRPCCredentials) CallOption {
|
||||
|
||||
// PerRPCCredsCallOption is a CallOption that indicates the per-RPC
|
||||
// credentials to use for the call.
|
||||
// This is an EXPERIMENTAL API.
|
||||
//
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This type is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
type PerRPCCredsCallOption struct {
|
||||
Creds credentials.PerRPCCredentials
|
||||
}
|
||||
@ -340,19 +362,26 @@ func (o PerRPCCredsCallOption) before(c *callInfo) error {
|
||||
c.creds = o.Creds
|
||||
return nil
|
||||
}
|
||||
func (o PerRPCCredsCallOption) after(c *callInfo) {}
|
||||
func (o PerRPCCredsCallOption) after(c *callInfo, attempt *csAttempt) {}
|
||||
|
||||
// UseCompressor returns a CallOption which sets the compressor used when
|
||||
// sending the request. If WithCompressor is also set, UseCompressor has
|
||||
// higher priority.
|
||||
//
|
||||
// This API is EXPERIMENTAL.
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This API is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
func UseCompressor(name string) CallOption {
|
||||
return CompressorCallOption{CompressorType: name}
|
||||
}
|
||||
|
||||
// CompressorCallOption is a CallOption that indicates the compressor to use.
|
||||
// This is an EXPERIMENTAL API.
|
||||
//
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This type is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
type CompressorCallOption struct {
|
||||
CompressorType string
|
||||
}
|
||||
@ -361,7 +390,7 @@ func (o CompressorCallOption) before(c *callInfo) error {
|
||||
c.compressorType = o.CompressorType
|
||||
return nil
|
||||
}
|
||||
func (o CompressorCallOption) after(c *callInfo) {}
|
||||
func (o CompressorCallOption) after(c *callInfo, attempt *csAttempt) {}
|
||||
|
||||
// CallContentSubtype returns a CallOption that will set the content-subtype
|
||||
// for a call. For example, if content-subtype is "json", the Content-Type over
|
||||
@ -385,7 +414,11 @@ func CallContentSubtype(contentSubtype string) CallOption {
|
||||
|
||||
// ContentSubtypeCallOption is a CallOption that indicates the content-subtype
|
||||
// used for marshaling messages.
|
||||
// This is an EXPERIMENTAL API.
|
||||
//
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This type is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
type ContentSubtypeCallOption struct {
|
||||
ContentSubtype string
|
||||
}
|
||||
@ -394,11 +427,12 @@ func (o ContentSubtypeCallOption) before(c *callInfo) error {
|
||||
c.contentSubtype = o.ContentSubtype
|
||||
return nil
|
||||
}
|
||||
func (o ContentSubtypeCallOption) after(c *callInfo) {}
|
||||
func (o ContentSubtypeCallOption) after(c *callInfo, attempt *csAttempt) {}
|
||||
|
||||
// ForceCodec returns a CallOption that will set the given Codec to be
|
||||
// used for all request and response messages for a call. The result of calling
|
||||
// String() will be used as the content-subtype in a case-insensitive manner.
|
||||
// ForceCodec returns a CallOption that will set codec to be used for all
|
||||
// request and response messages for a call. The result of calling Name() will
|
||||
// be used as the content-subtype after converting to lowercase, unless
|
||||
// CallContentSubtype is also used.
|
||||
//
|
||||
// See Content-Type on
|
||||
// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests for
|
||||
@ -409,7 +443,10 @@ func (o ContentSubtypeCallOption) after(c *callInfo) {}
|
||||
// This function is provided for advanced users; prefer to use only
|
||||
// CallContentSubtype to select a registered codec instead.
|
||||
//
|
||||
// This is an EXPERIMENTAL API.
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This API is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
func ForceCodec(codec encoding.Codec) CallOption {
|
||||
return ForceCodecCallOption{Codec: codec}
|
||||
}
|
||||
@ -417,7 +454,10 @@ func ForceCodec(codec encoding.Codec) CallOption {
|
||||
// ForceCodecCallOption is a CallOption that indicates the codec used for
|
||||
// marshaling messages.
|
||||
//
|
||||
// This is an EXPERIMENTAL API.
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This type is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
type ForceCodecCallOption struct {
|
||||
Codec encoding.Codec
|
||||
}
|
||||
@ -426,7 +466,7 @@ func (o ForceCodecCallOption) before(c *callInfo) error {
|
||||
c.codec = o.Codec
|
||||
return nil
|
||||
}
|
||||
func (o ForceCodecCallOption) after(c *callInfo) {}
|
||||
func (o ForceCodecCallOption) after(c *callInfo, attempt *csAttempt) {}
|
||||
|
||||
// CallCustomCodec behaves like ForceCodec, but accepts a grpc.Codec instead of
|
||||
// an encoding.Codec.
|
||||
@ -439,7 +479,10 @@ func CallCustomCodec(codec Codec) CallOption {
|
||||
// CustomCodecCallOption is a CallOption that indicates the codec used for
|
||||
// marshaling messages.
|
||||
//
|
||||
// This is an EXPERIMENTAL API.
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This type is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
type CustomCodecCallOption struct {
|
||||
Codec Codec
|
||||
}
|
||||
@ -448,19 +491,26 @@ func (o CustomCodecCallOption) before(c *callInfo) error {
|
||||
c.codec = o.Codec
|
||||
return nil
|
||||
}
|
||||
func (o CustomCodecCallOption) after(c *callInfo) {}
|
||||
func (o CustomCodecCallOption) after(c *callInfo, attempt *csAttempt) {}
|
||||
|
||||
// MaxRetryRPCBufferSize returns a CallOption that limits the amount of memory
|
||||
// used for buffering this RPC's requests for retry purposes.
|
||||
//
|
||||
// This API is EXPERIMENTAL.
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This API is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
func MaxRetryRPCBufferSize(bytes int) CallOption {
|
||||
return MaxRetryRPCBufferSizeCallOption{bytes}
|
||||
}
|
||||
|
||||
// MaxRetryRPCBufferSizeCallOption is a CallOption indicating the amount of
|
||||
// memory to be used for caching this RPC for retry purposes.
|
||||
// This is an EXPERIMENTAL API.
|
||||
//
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This type is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
type MaxRetryRPCBufferSizeCallOption struct {
|
||||
MaxRetryRPCBufferSize int
|
||||
}
|
||||
@ -469,7 +519,7 @@ func (o MaxRetryRPCBufferSizeCallOption) before(c *callInfo) error {
|
||||
c.maxRetryRPCBufferSize = o.MaxRetryRPCBufferSize
|
||||
return nil
|
||||
}
|
||||
func (o MaxRetryRPCBufferSizeCallOption) after(c *callInfo) {}
|
||||
func (o MaxRetryRPCBufferSizeCallOption) after(c *callInfo, attempt *csAttempt) {}
|
||||
|
||||
// The format of the payload: compressed or not?
|
||||
type payloadFormat uint8
|
||||
@ -648,35 +698,58 @@ func recvAndDecompress(p *parser, s *transport.Stream, dc Decompressor, maxRecei
|
||||
return nil, st.Err()
|
||||
}
|
||||
|
||||
var size int
|
||||
if pf == compressionMade {
|
||||
// To match legacy behavior, if the decompressor is set by WithDecompressor or RPCDecompressor,
|
||||
// use this decompressor as the default.
|
||||
if dc != nil {
|
||||
d, err = dc.Do(bytes.NewReader(d))
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message %v", err)
|
||||
}
|
||||
size = len(d)
|
||||
} else {
|
||||
dcReader, err := compressor.Decompress(bytes.NewReader(d))
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message %v", err)
|
||||
}
|
||||
// Read from LimitReader with limit max+1. So if the underlying
|
||||
// reader is over limit, the result will be bigger than max.
|
||||
d, err = ioutil.ReadAll(io.LimitReader(dcReader, int64(maxReceiveMessageSize)+1))
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message %v", err)
|
||||
}
|
||||
d, size, err = decompress(compressor, d, maxReceiveMessageSize)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message %v", err)
|
||||
}
|
||||
} else {
|
||||
size = len(d)
|
||||
}
|
||||
if len(d) > maxReceiveMessageSize {
|
||||
if size > maxReceiveMessageSize {
|
||||
// TODO: Revisit the error code. Currently keep it consistent with java
|
||||
// implementation.
|
||||
return nil, status.Errorf(codes.ResourceExhausted, "grpc: received message larger than max (%d vs. %d)", len(d), maxReceiveMessageSize)
|
||||
return nil, status.Errorf(codes.ResourceExhausted, "grpc: received message larger than max (%d vs. %d)", size, maxReceiveMessageSize)
|
||||
}
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// Using compressor, decompress d, returning data and size.
|
||||
// Optionally, if data will be over maxReceiveMessageSize, just return the size.
|
||||
func decompress(compressor encoding.Compressor, d []byte, maxReceiveMessageSize int) ([]byte, int, error) {
|
||||
dcReader, err := compressor.Decompress(bytes.NewReader(d))
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
if sizer, ok := compressor.(interface {
|
||||
DecompressedSize(compressedBytes []byte) int
|
||||
}); ok {
|
||||
if size := sizer.DecompressedSize(d); size >= 0 {
|
||||
if size > maxReceiveMessageSize {
|
||||
return nil, size, nil
|
||||
}
|
||||
// size is used as an estimate to size the buffer, but we
|
||||
// will read more data if available.
|
||||
// +MinRead so ReadFrom will not reallocate if size is correct.
|
||||
buf := bytes.NewBuffer(make([]byte, 0, size+bytes.MinRead))
|
||||
bytesRead, err := buf.ReadFrom(io.LimitReader(dcReader, int64(maxReceiveMessageSize)+1))
|
||||
return buf.Bytes(), int(bytesRead), err
|
||||
}
|
||||
}
|
||||
// Read from LimitReader with limit max+1. So if the underlying
|
||||
// reader is over limit, the result will be bigger than max.
|
||||
d, err = ioutil.ReadAll(io.LimitReader(dcReader, int64(maxReceiveMessageSize)+1))
|
||||
return d, len(d), err
|
||||
}
|
||||
|
||||
// For the two compressor parameters, both should not be set, but if they are,
|
||||
// dc takes precedence over compressor.
|
||||
// TODO(dfawley): wrap the old compressor/decompressor using the new API?
|
||||
@ -781,7 +854,17 @@ func toRPCErr(err error) error {
|
||||
// setCallInfoCodec should only be called after CallOptions have been applied.
|
||||
func setCallInfoCodec(c *callInfo) error {
|
||||
if c.codec != nil {
|
||||
// codec was already set by a CallOption; use it.
|
||||
// codec was already set by a CallOption; use it, but set the content
|
||||
// subtype if it is not set.
|
||||
if c.contentSubtype == "" {
|
||||
// c.codec is a baseCodec to hide the difference between grpc.Codec and
|
||||
// encoding.Codec (Name vs. String method name). We only support
|
||||
// setting content subtype from encoding.Codec to avoid a behavior
|
||||
// change with the deprecated version.
|
||||
if ec, ok := c.codec.(encoding.Codec); ok {
|
||||
c.contentSubtype = strings.ToLower(ec.Name())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -799,40 +882,6 @@ func setCallInfoCodec(c *callInfo) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// parseDialTarget returns the network and address to pass to dialer
|
||||
func parseDialTarget(target string) (net string, addr string) {
|
||||
net = "tcp"
|
||||
|
||||
m1 := strings.Index(target, ":")
|
||||
m2 := strings.Index(target, ":/")
|
||||
|
||||
// handle unix:addr which will fail with url.Parse
|
||||
if m1 >= 0 && m2 < 0 {
|
||||
if n := target[0:m1]; n == "unix" {
|
||||
net = n
|
||||
addr = target[m1+1:]
|
||||
return net, addr
|
||||
}
|
||||
}
|
||||
if m2 >= 0 {
|
||||
t, err := url.Parse(target)
|
||||
if err != nil {
|
||||
return net, target
|
||||
}
|
||||
scheme := t.Scheme
|
||||
addr = t.Path
|
||||
if scheme == "unix" {
|
||||
net = scheme
|
||||
if addr == "" {
|
||||
addr = t.Host
|
||||
}
|
||||
return net, addr
|
||||
}
|
||||
}
|
||||
|
||||
return net, target
|
||||
}
|
||||
|
||||
// channelzData is used to store channelz related data for ClientConn, addrConn and Server.
|
||||
// These fields cannot be embedded in the original structs (e.g. ClientConn), since to do atomic
|
||||
// operation on int64 variable on 32-bit machine, user is responsible to enforce memory alignment.
|
||||
@ -848,16 +897,17 @@ type channelzData struct {
|
||||
|
||||
// The SupportPackageIsVersion variables are referenced from generated protocol
|
||||
// buffer files to ensure compatibility with the gRPC version used. The latest
|
||||
// support package version is 5.
|
||||
// support package version is 7.
|
||||
//
|
||||
// Older versions are kept for compatibility. They may be removed if
|
||||
// compatibility cannot be maintained.
|
||||
// Older versions are kept for compatibility.
|
||||
//
|
||||
// These constants should not be referenced from any other code.
|
||||
const (
|
||||
SupportPackageIsVersion3 = true
|
||||
SupportPackageIsVersion4 = true
|
||||
SupportPackageIsVersion5 = true
|
||||
SupportPackageIsVersion6 = true
|
||||
SupportPackageIsVersion7 = true
|
||||
)
|
||||
|
||||
const grpcUA = "grpc-go/" + Version
|
||||
|
Reference in New Issue
Block a user