mirror of
https://github.com/taigrr/wasm-experiments
synced 2025-01-18 04:03:21 -08:00
Use custom for of grpc-go and unify client and server
This commit is contained in:
parent
3d89b1de82
commit
c7ec9fde8c
18
Gopkg.lock
generated
18
Gopkg.lock
generated
@ -32,10 +32,11 @@
|
|||||||
version = "v1.2.0"
|
version = "v1.2.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
|
branch = "set-content-type-in-response"
|
||||||
name = "github.com/improbable-eng/grpc-web"
|
name = "github.com/improbable-eng/grpc-web"
|
||||||
packages = ["go/grpcweb"]
|
packages = ["go/grpcweb"]
|
||||||
revision = "72eb701d6f320ca324b3347c7925a720b553eae5"
|
revision = "4883019eae31cf9b891633279c6a92d0597ea920"
|
||||||
version = "0.6.2"
|
source = "github.com/johanbrandhorst/grpc-web"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
@ -47,7 +48,6 @@
|
|||||||
branch = "master"
|
branch = "master"
|
||||||
name = "github.com/johanbrandhorst/grpc-wasm"
|
name = "github.com/johanbrandhorst/grpc-wasm"
|
||||||
packages = [
|
packages = [
|
||||||
".",
|
|
||||||
"protoc-gen-wasm",
|
"protoc-gen-wasm",
|
||||||
"protoc-gen-wasm/generator",
|
"protoc-gen-wasm/generator",
|
||||||
"protoc-gen-wasm/generator/internal/remap",
|
"protoc-gen-wasm/generator/internal/remap",
|
||||||
@ -145,21 +145,23 @@
|
|||||||
revision = "86e600f69ee4704c6efbf6a2a40a5c10700e76c2"
|
revision = "86e600f69ee4704c6efbf6a2a40a5c10700e76c2"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
|
branch = "add-grpc-web-client"
|
||||||
name = "google.golang.org/grpc"
|
name = "google.golang.org/grpc"
|
||||||
packages = [
|
packages = [
|
||||||
".",
|
".",
|
||||||
"balancer",
|
"balancer",
|
||||||
"balancer/base",
|
"balancer/base",
|
||||||
"balancer/roundrobin",
|
"balancer/roundrobin",
|
||||||
"channelz",
|
|
||||||
"codes",
|
"codes",
|
||||||
"connectivity",
|
"connectivity",
|
||||||
"credentials",
|
"credentials",
|
||||||
"encoding",
|
"encoding",
|
||||||
"encoding/proto",
|
"encoding/proto",
|
||||||
"grpclb/grpc_lb_v1/messages",
|
|
||||||
"grpclog",
|
"grpclog",
|
||||||
"internal",
|
"internal",
|
||||||
|
"internal/backoff",
|
||||||
|
"internal/channelz",
|
||||||
|
"internal/grpcrand",
|
||||||
"keepalive",
|
"keepalive",
|
||||||
"metadata",
|
"metadata",
|
||||||
"naming",
|
"naming",
|
||||||
@ -172,12 +174,12 @@
|
|||||||
"tap",
|
"tap",
|
||||||
"transport"
|
"transport"
|
||||||
]
|
]
|
||||||
revision = "41344da2231b913fa3d983840a57a6b1b7b631a1"
|
revision = "43e0a181510c90bb1c9a9a3d73f33df55bd21295"
|
||||||
version = "v1.12.0"
|
source = "github.com/johanbrandhorst/grpc-go"
|
||||||
|
|
||||||
[solve-meta]
|
[solve-meta]
|
||||||
analyzer-name = "dep"
|
analyzer-name = "dep"
|
||||||
analyzer-version = 1
|
analyzer-version = 1
|
||||||
inputs-digest = "32259474a7120b027d79b02dc0b1f1f13673342b660d3f55bcc442b6499ee37c"
|
inputs-digest = "efb2981e5b7917b202cb0cfb3d8782af1275313b68c739acabf2ccd70258fd97"
|
||||||
solver-name = "gps-cdcl"
|
solver-name = "gps-cdcl"
|
||||||
solver-version = 1
|
solver-version = 1
|
||||||
|
21
Gopkg.toml
21
Gopkg.toml
@ -3,14 +3,6 @@ required = [
|
|||||||
"github.com/golang/protobuf/protoc-gen-go",
|
"github.com/golang/protobuf/protoc-gen-go",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[constraint]]
|
|
||||||
branch = "master"
|
|
||||||
name = "github.com/johanbrandhorst/fetch"
|
|
||||||
|
|
||||||
[[constraint]]
|
|
||||||
branch = "master"
|
|
||||||
name = "github.com/johanbrandhorst/grpc-wasm"
|
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
name = "github.com/golang/protobuf"
|
name = "github.com/golang/protobuf"
|
||||||
@ -20,8 +12,19 @@ required = [
|
|||||||
name = "google.golang.org/genproto"
|
name = "google.golang.org/genproto"
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
version = "1.12.0"
|
branch = "add-grpc-web-client"
|
||||||
name = "google.golang.org/grpc"
|
name = "google.golang.org/grpc"
|
||||||
|
source = "github.com/johanbrandhorst/grpc-go"
|
||||||
|
|
||||||
|
[[override]]
|
||||||
|
branch = "add-grpc-web-client"
|
||||||
|
name = "google.golang.org/grpc"
|
||||||
|
source = "github.com/johanbrandhorst/grpc-go"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
branch = "set-content-type-in-response"
|
||||||
|
name = "github.com/improbable-eng/grpc-web"
|
||||||
|
source = "github.com/johanbrandhorst/grpc-web"
|
||||||
|
|
||||||
[prune]
|
[prune]
|
||||||
go-tests = true
|
go-tests = true
|
||||||
|
@ -4,4 +4,4 @@ clean:
|
|||||||
rm -f ../html/test.wasm
|
rm -f ../html/test.wasm
|
||||||
|
|
||||||
compile:
|
compile:
|
||||||
GOOS=js GOARCH=wasm GOROOT=$(GOPATH)/src/github.com/neelance/go/ $(GOPATH)/src/github.com/neelance/go/bin/go build -o ../html/test.wasm main.go
|
GOOS=js GOARCH=wasm GOROOT=$(GOPATH)/src/github.com/johanbrandhorst/go/ $(GOPATH)/src/github.com/johanbrandhorst/go/bin/go build -o ../html/test.wasm main.go
|
||||||
|
@ -1,9 +1,37 @@
|
|||||||
generate:
|
generate:
|
||||||
protoc -I. ./proto/web.proto \
|
protoc -I. ./proto/web.proto \
|
||||||
--go_out=plugins=grpc:$$GOPATH/src \
|
--go_out=plugins=grpc:$$GOPATH/src
|
||||||
--wasm_out=plugins=grpc:./
|
|
||||||
mv ./proto/web.wasm.pb.go ./proto/client/
|
|
||||||
go generate -x ./frontend/
|
go generate -x ./frontend/
|
||||||
|
|
||||||
|
to_frontend:
|
||||||
|
cd ../../../../google.golang.org/grpc && \
|
||||||
|
mv -f parse_js.gox parse_js.go && \
|
||||||
|
mv -f parse.go parse.gox && \
|
||||||
|
mv -f newstream_js.gox newstream_js.go && \
|
||||||
|
mv -f newstream.go newstream.gox && \
|
||||||
|
mv -f dial_js.gox dial_js.go && \
|
||||||
|
mv -f dial.go dial.gox && \
|
||||||
|
mv -f transport/stream_js.gox transport/stream_js.go && \
|
||||||
|
mv -f transport/stream.go transport/stream.gox && \
|
||||||
|
mv -f transport/client_transport_js.gox transport/client_transport_js.go && \
|
||||||
|
mv -f transport/client_transport.go transport/client_transport.gox && \
|
||||||
|
mv -f transport/content_type_js.gox transport/content_type_js.go && \
|
||||||
|
mv -f transport/content_type.go transport/content_type.gox
|
||||||
|
|
||||||
|
to_backend:
|
||||||
|
cd ../../../../google.golang.org/grpc && \
|
||||||
|
mv -f parse_js.go parse_js.gox && \
|
||||||
|
mv -f parse.gox parse.go && \
|
||||||
|
mv -f newstream_js.go newstream_js.gox && \
|
||||||
|
mv -f newstream.gox newstream.go && \
|
||||||
|
mv -f dial_js.go dial_js.gox && \
|
||||||
|
mv -f dial.gox dial.go && \
|
||||||
|
mv -f transport/stream_js.go transport/stream_js.gox && \
|
||||||
|
mv -f transport/stream.gox transport/stream.go && \
|
||||||
|
mv -f transport/client_transport_js.go transport/client_transport_js.gox && \
|
||||||
|
mv -f transport/client_transport.gox transport/client_transport.go && \
|
||||||
|
mv -f transport/content_type_js.go transport/content_type_js.gox && \
|
||||||
|
mv -f transport/content_type.gox transport/content_type.go
|
||||||
|
|
||||||
serve:
|
serve:
|
||||||
go run main.go
|
go run main.go
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
|
|
||||||
"github.com/johanbrandhorst/wasm-experiments/grpc/proto/server"
|
web "github.com/johanbrandhorst/wasm-experiments/grpc/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Backend should be used to implement the server interface
|
// Backend should be used to implement the server interface
|
||||||
@ -18,9 +18,9 @@ type Backend struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ensure struct implements interface
|
// Ensure struct implements interface
|
||||||
var _ server.BackendServer = (*Backend)(nil)
|
var _ web.BackendServer = (*Backend)(nil)
|
||||||
|
|
||||||
func (b Backend) GetUser(ctx context.Context, req *server.GetUserRequest) (*server.User, error) {
|
func (b Backend) GetUser(ctx context.Context, req *web.GetUserRequest) (*web.User, error) {
|
||||||
if req.GetUserId() != "1234" {
|
if req.GetUserId() != "1234" {
|
||||||
st := status.New(codes.InvalidArgument, "invalid id")
|
st := status.New(codes.InvalidArgument, "invalid id")
|
||||||
detSt, err := st.WithDetails(&errdetails.BadRequest{
|
detSt, err := st.WithDetails(&errdetails.BadRequest{
|
||||||
@ -36,14 +36,14 @@ func (b Backend) GetUser(ctx context.Context, req *server.GetUserRequest) (*serv
|
|||||||
}
|
}
|
||||||
return nil, st.Err()
|
return nil, st.Err()
|
||||||
}
|
}
|
||||||
return &server.User{
|
return &web.User{
|
||||||
Id: req.GetUserId(),
|
Id: req.GetUserId(),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b Backend) GetUsers(req *server.GetUsersRequest, srv server.Backend_GetUsersServer) error {
|
func (b Backend) GetUsers(req *web.GetUsersRequest, srv web.Backend_GetUsersServer) error {
|
||||||
for index := 0; index < int(req.GetNumUsers()); index++ {
|
for index := 0; index < int(req.GetNumUsers()); index++ {
|
||||||
err := srv.Send(&server.User{
|
err := srv.Send(&web.User{
|
||||||
Id: strconv.Itoa(index),
|
Id: strconv.Itoa(index),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
File diff suppressed because one or more lines are too long
@ -4,25 +4,36 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"os"
|
||||||
|
|
||||||
_ "google.golang.org/genproto/googleapis/rpc/errdetails"
|
_ "google.golang.org/genproto/googleapis/rpc/errdetails"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
"google.golang.org/grpc/grpclog"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
|
|
||||||
grpc "github.com/johanbrandhorst/grpc-wasm"
|
web "github.com/johanbrandhorst/wasm-experiments/grpc/proto"
|
||||||
server "github.com/johanbrandhorst/wasm-experiments/grpc/proto/client"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Build with Go WASM fork
|
// Build with Go WASM fork
|
||||||
//go:generate rm -f ./html/test.wasm
|
//go:generate rm -f ./html/test.wasm
|
||||||
//go:generate bash -c "GOOS=js GOARCH=wasm GOROOT=$GOPATH/src/github.com/neelance/go/ $GOPATH/src/github.com/neelance/go/bin/go build -o ./html/test.wasm frontend.go"
|
//go:generate bash -c "GOOS=js GOARCH=wasm GOROOT=$GOPATH/src/github.com/johanbrandhorst/go/ $GOPATH/src/github.com/johanbrandhorst/go/bin/go build -o ./html/test.wasm frontend.go"
|
||||||
|
|
||||||
// Integrate generated JS into a Go file for static loading.
|
// Integrate generated JS into a Go file for static loading.
|
||||||
//go:generate bash -c "go run assets_generate.go"
|
//go:generate bash -c "go run assets_generate.go"
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// Should only be done from init functions
|
||||||
|
grpclog.SetLoggerV2(grpclog.NewLoggerV2(os.Stdout, os.Stdout, os.Stdout))
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
cc, _ := grpc.Dial("")
|
cc, err := grpc.Dial("")
|
||||||
client := server.NewBackendClient(cc)
|
if err != nil {
|
||||||
resp, err := client.GetUser(context.Background(), &server.GetUserRequest{
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
client := web.NewBackendClient(cc)
|
||||||
|
resp, err := client.GetUser(context.Background(), &web.GetUserRequest{
|
||||||
UserId: "1234",
|
UserId: "1234",
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -31,7 +42,7 @@ func main() {
|
|||||||
} else {
|
} else {
|
||||||
fmt.Println(resp.GetId())
|
fmt.Println(resp.GetId())
|
||||||
}
|
}
|
||||||
resp, err = client.GetUser(context.Background(), &server.GetUserRequest{
|
resp, err = client.GetUser(context.Background(), &web.GetUserRequest{
|
||||||
UserId: "123",
|
UserId: "123",
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -41,7 +52,7 @@ func main() {
|
|||||||
fmt.Println(resp.GetId())
|
fmt.Println(resp.GetId())
|
||||||
}
|
}
|
||||||
|
|
||||||
srv, err := client.GetUsers(context.Background(), &server.GetUsersRequest{
|
srv, err := client.GetUsers(context.Background(), &web.GetUsersRequest{
|
||||||
NumUsers: 3,
|
NumUsers: 3,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -41,6 +41,11 @@
|
|||||||
}
|
}
|
||||||
return buf.length;
|
return buf.length;
|
||||||
},
|
},
|
||||||
|
openSync(path, flags, mode) {
|
||||||
|
const err = new Error("not implemented");
|
||||||
|
err.code = "ENOSYS";
|
||||||
|
throw err;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,6 +374,7 @@
|
|||||||
return go.run(result.instance);
|
return go.run(result.instance);
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
go.exited = true;
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ import (
|
|||||||
|
|
||||||
"github.com/johanbrandhorst/wasm-experiments/grpc/backend"
|
"github.com/johanbrandhorst/wasm-experiments/grpc/backend"
|
||||||
"github.com/johanbrandhorst/wasm-experiments/grpc/frontend/bundle"
|
"github.com/johanbrandhorst/wasm-experiments/grpc/frontend/bundle"
|
||||||
"github.com/johanbrandhorst/wasm-experiments/grpc/proto/server"
|
web "github.com/johanbrandhorst/wasm-experiments/grpc/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
var logger *logrus.Logger
|
var logger *logrus.Logger
|
||||||
@ -39,7 +39,7 @@ func init() {
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
gs := grpc.NewServer()
|
gs := grpc.NewServer()
|
||||||
server.RegisterBackendServer(gs, &backend.Backend{})
|
web.RegisterBackendServer(gs, &backend.Backend{})
|
||||||
wrappedServer := grpcweb.WrapServer(gs, grpcweb.WithWebsockets(true))
|
wrappedServer := grpcweb.WrapServer(gs, grpcweb.WithWebsockets(true))
|
||||||
|
|
||||||
handler := func(resp http.ResponseWriter, req *http.Request) {
|
handler := func(resp http.ResponseWriter, req *http.Request) {
|
||||||
|
@ -1,302 +0,0 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
|
||||||
// source: proto/web.proto
|
|
||||||
|
|
||||||
package server
|
|
||||||
|
|
||||||
/*
|
|
||||||
Web exposes a backend server over gRPC.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import proto "github.com/golang/protobuf/proto"
|
|
||||||
import fmt "fmt"
|
|
||||||
import math "math"
|
|
||||||
|
|
||||||
import (
|
|
||||||
context "golang.org/x/net/context"
|
|
||||||
grpc "github.com/johanbrandhorst/grpc-wasm"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Reference imports to suppress errors if they are not otherwise used.
|
|
||||||
var _ = proto.Marshal
|
|
||||||
var _ = fmt.Errorf
|
|
||||||
var _ = math.Inf
|
|
||||||
|
|
||||||
// This is a compile-time assertion to ensure that this generated file
|
|
||||||
// is compatible with the proto package it is being compiled against.
|
|
||||||
// A compilation error at this line likely means your copy of the
|
|
||||||
// proto package needs to be updated.
|
|
||||||
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
|
||||||
|
|
||||||
type GetUserRequest struct {
|
|
||||||
UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
|
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
|
||||||
XXX_unrecognized []byte `json:"-"`
|
|
||||||
XXX_sizecache int32 `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *GetUserRequest) Reset() { *m = GetUserRequest{} }
|
|
||||||
func (m *GetUserRequest) String() string { return proto.CompactTextString(m) }
|
|
||||||
func (*GetUserRequest) ProtoMessage() {}
|
|
||||||
func (*GetUserRequest) Descriptor() ([]byte, []int) {
|
|
||||||
return fileDescriptor_web_87670d45010119fa, []int{0}
|
|
||||||
}
|
|
||||||
func (m *GetUserRequest) XXX_Unmarshal(b []byte) error {
|
|
||||||
return xxx_messageInfo_GetUserRequest.Unmarshal(m, b)
|
|
||||||
}
|
|
||||||
func (m *GetUserRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
|
||||||
return xxx_messageInfo_GetUserRequest.Marshal(b, m, deterministic)
|
|
||||||
}
|
|
||||||
func (dst *GetUserRequest) XXX_Merge(src proto.Message) {
|
|
||||||
xxx_messageInfo_GetUserRequest.Merge(dst, src)
|
|
||||||
}
|
|
||||||
func (m *GetUserRequest) XXX_Size() int {
|
|
||||||
return xxx_messageInfo_GetUserRequest.Size(m)
|
|
||||||
}
|
|
||||||
func (m *GetUserRequest) XXX_DiscardUnknown() {
|
|
||||||
xxx_messageInfo_GetUserRequest.DiscardUnknown(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
var xxx_messageInfo_GetUserRequest proto.InternalMessageInfo
|
|
||||||
|
|
||||||
func (m *GetUserRequest) GetUserId() string {
|
|
||||||
if m != nil {
|
|
||||||
return m.UserId
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
type User struct {
|
|
||||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
|
||||||
XXX_unrecognized []byte `json:"-"`
|
|
||||||
XXX_sizecache int32 `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *User) Reset() { *m = User{} }
|
|
||||||
func (m *User) String() string { return proto.CompactTextString(m) }
|
|
||||||
func (*User) ProtoMessage() {}
|
|
||||||
func (*User) Descriptor() ([]byte, []int) {
|
|
||||||
return fileDescriptor_web_87670d45010119fa, []int{1}
|
|
||||||
}
|
|
||||||
func (m *User) XXX_Unmarshal(b []byte) error {
|
|
||||||
return xxx_messageInfo_User.Unmarshal(m, b)
|
|
||||||
}
|
|
||||||
func (m *User) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
|
||||||
return xxx_messageInfo_User.Marshal(b, m, deterministic)
|
|
||||||
}
|
|
||||||
func (dst *User) XXX_Merge(src proto.Message) {
|
|
||||||
xxx_messageInfo_User.Merge(dst, src)
|
|
||||||
}
|
|
||||||
func (m *User) XXX_Size() int {
|
|
||||||
return xxx_messageInfo_User.Size(m)
|
|
||||||
}
|
|
||||||
func (m *User) XXX_DiscardUnknown() {
|
|
||||||
xxx_messageInfo_User.DiscardUnknown(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
var xxx_messageInfo_User proto.InternalMessageInfo
|
|
||||||
|
|
||||||
func (m *User) GetId() string {
|
|
||||||
if m != nil {
|
|
||||||
return m.Id
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
type GetUsersRequest struct {
|
|
||||||
NumUsers int64 `protobuf:"varint,1,opt,name=num_users,json=numUsers,proto3" json:"num_users,omitempty"`
|
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
|
||||||
XXX_unrecognized []byte `json:"-"`
|
|
||||||
XXX_sizecache int32 `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *GetUsersRequest) Reset() { *m = GetUsersRequest{} }
|
|
||||||
func (m *GetUsersRequest) String() string { return proto.CompactTextString(m) }
|
|
||||||
func (*GetUsersRequest) ProtoMessage() {}
|
|
||||||
func (*GetUsersRequest) Descriptor() ([]byte, []int) {
|
|
||||||
return fileDescriptor_web_87670d45010119fa, []int{2}
|
|
||||||
}
|
|
||||||
func (m *GetUsersRequest) XXX_Unmarshal(b []byte) error {
|
|
||||||
return xxx_messageInfo_GetUsersRequest.Unmarshal(m, b)
|
|
||||||
}
|
|
||||||
func (m *GetUsersRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
|
||||||
return xxx_messageInfo_GetUsersRequest.Marshal(b, m, deterministic)
|
|
||||||
}
|
|
||||||
func (dst *GetUsersRequest) XXX_Merge(src proto.Message) {
|
|
||||||
xxx_messageInfo_GetUsersRequest.Merge(dst, src)
|
|
||||||
}
|
|
||||||
func (m *GetUsersRequest) XXX_Size() int {
|
|
||||||
return xxx_messageInfo_GetUsersRequest.Size(m)
|
|
||||||
}
|
|
||||||
func (m *GetUsersRequest) XXX_DiscardUnknown() {
|
|
||||||
xxx_messageInfo_GetUsersRequest.DiscardUnknown(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
var xxx_messageInfo_GetUsersRequest proto.InternalMessageInfo
|
|
||||||
|
|
||||||
func (m *GetUsersRequest) GetNumUsers() int64 {
|
|
||||||
if m != nil {
|
|
||||||
return m.NumUsers
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
proto.RegisterType((*GetUserRequest)(nil), "web.GetUserRequest")
|
|
||||||
proto.RegisterType((*User)(nil), "web.User")
|
|
||||||
proto.RegisterType((*GetUsersRequest)(nil), "web.GetUsersRequest")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reference imports to suppress errors if they are not otherwise used.
|
|
||||||
var _ context.Context
|
|
||||||
var _ grpc.ClientConn
|
|
||||||
|
|
||||||
// This is a compile-time assertion to ensure that this generated file
|
|
||||||
// is compatible with the grpc package it is being compiled against.
|
|
||||||
const _ = grpc.SupportPackageIsVersion4
|
|
||||||
|
|
||||||
// BackendClient is the client API for Backend service.
|
|
||||||
//
|
|
||||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
|
||||||
type BackendClient interface {
|
|
||||||
GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc.CallOption) (*User, error)
|
|
||||||
GetUsers(ctx context.Context, in *GetUsersRequest, opts ...grpc.CallOption) (Backend_GetUsersClient, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type backendClient struct {
|
|
||||||
cc *grpc.ClientConn
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewBackendClient(cc *grpc.ClientConn) BackendClient {
|
|
||||||
return &backendClient{cc}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *backendClient) GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc.CallOption) (*User, error) {
|
|
||||||
out := new(User)
|
|
||||||
err := c.cc.Invoke(ctx, "/web.Backend/GetUser", in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *backendClient) GetUsers(ctx context.Context, in *GetUsersRequest, opts ...grpc.CallOption) (Backend_GetUsersClient, error) {
|
|
||||||
stream, err := c.cc.NewStream(ctx, &_Backend_serviceDesc.Streams[0], "/web.Backend/GetUsers", opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
x := &backendGetUsersClient{stream}
|
|
||||||
if err := x.ClientStream.SendMsg(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err := x.ClientStream.CloseSend(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return x, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type Backend_GetUsersClient interface {
|
|
||||||
Recv() (*User, error)
|
|
||||||
grpc.ClientStream
|
|
||||||
}
|
|
||||||
|
|
||||||
type backendGetUsersClient struct {
|
|
||||||
grpc.ClientStream
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *backendGetUsersClient) Recv() (*User, error) {
|
|
||||||
m := new(User)
|
|
||||||
if err := x.ClientStream.RecvMsg(m); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return m, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// BackendServer is the server API for Backend service.
|
|
||||||
type BackendServer interface {
|
|
||||||
GetUser(context.Context, *GetUserRequest) (*User, error)
|
|
||||||
GetUsers(*GetUsersRequest, Backend_GetUsersServer) error
|
|
||||||
}
|
|
||||||
|
|
||||||
func RegisterBackendServer(s *grpc.Server, srv BackendServer) {
|
|
||||||
s.RegisterService(&_Backend_serviceDesc, srv)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _Backend_GetUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(GetUserRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(BackendServer).GetUser(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: "/web.Backend/GetUser",
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(BackendServer).GetUser(ctx, req.(*GetUserRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _Backend_GetUsers_Handler(srv interface{}, stream grpc.ServerStream) error {
|
|
||||||
m := new(GetUsersRequest)
|
|
||||||
if err := stream.RecvMsg(m); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return srv.(BackendServer).GetUsers(m, &backendGetUsersServer{stream})
|
|
||||||
}
|
|
||||||
|
|
||||||
type Backend_GetUsersServer interface {
|
|
||||||
Send(*User) error
|
|
||||||
grpc.ServerStream
|
|
||||||
}
|
|
||||||
|
|
||||||
type backendGetUsersServer struct {
|
|
||||||
grpc.ServerStream
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *backendGetUsersServer) Send(m *User) error {
|
|
||||||
return x.ServerStream.SendMsg(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
var _Backend_serviceDesc = grpc.ServiceDesc{
|
|
||||||
ServiceName: "web.Backend",
|
|
||||||
HandlerType: (*BackendServer)(nil),
|
|
||||||
Methods: []grpc.MethodDesc{
|
|
||||||
{
|
|
||||||
MethodName: "GetUser",
|
|
||||||
Handler: _Backend_GetUser_Handler,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Streams: []grpc.StreamDesc{
|
|
||||||
{
|
|
||||||
StreamName: "GetUsers",
|
|
||||||
Handler: _Backend_GetUsers_Handler,
|
|
||||||
ServerStreams: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Metadata: "proto/web.proto",
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() { proto.RegisterFile("proto/web.proto", fileDescriptor_web_87670d45010119fa) }
|
|
||||||
|
|
||||||
var fileDescriptor_web_87670d45010119fa = []byte{
|
|
||||||
// 236 bytes of a gzipped FileDescriptorProto
|
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0xc1, 0x4b, 0xc3, 0x30,
|
|
||||||
0x18, 0xc5, 0xdd, 0x26, 0xeb, 0xfa, 0x1d, 0x36, 0x88, 0xa2, 0xa2, 0x17, 0xe9, 0x49, 0x11, 0x1b,
|
|
||||||
0xd1, 0xb3, 0x08, 0xbb, 0x88, 0xd7, 0x82, 0x17, 0x2f, 0xa3, 0x69, 0x3e, 0xda, 0x2a, 0x49, 0xea,
|
|
||||||
0xf7, 0x25, 0xd6, 0x3f, 0x5f, 0x12, 0x37, 0x51, 0xf0, 0x96, 0xf7, 0xf2, 0x7b, 0x2f, 0x8f, 0xc0,
|
|
||||||
0x6a, 0x20, 0xe7, 0x9d, 0x1c, 0x51, 0x95, 0xe9, 0x24, 0x66, 0x23, 0xaa, 0xe2, 0x12, 0x96, 0x8f,
|
|
||||||
0xe8, 0x9f, 0x19, 0xa9, 0xc2, 0xf7, 0x80, 0xec, 0xc5, 0x31, 0x64, 0x81, 0x91, 0x36, 0xbd, 0x3e,
|
|
||||||
0x99, 0x9c, 0x4f, 0x2e, 0xf2, 0x6a, 0x1e, 0xe5, 0x93, 0x2e, 0x8e, 0x60, 0x3f, 0x72, 0x62, 0x09,
|
|
||||||
0xd3, 0x9f, 0xbb, 0x69, 0xaf, 0x8b, 0x12, 0x56, 0xdb, 0x0a, 0xde, 0x75, 0x9c, 0x41, 0x6e, 0x83,
|
|
||||||
0xd9, 0xc4, 0x20, 0x27, 0x72, 0x56, 0x2d, 0x6c, 0x30, 0x89, 0xb9, 0x6d, 0x21, 0x5b, 0xd7, 0xcd,
|
|
||||||
0x1b, 0x5a, 0x2d, 0xae, 0x20, 0xdb, 0x46, 0xc5, 0x41, 0x19, 0x97, 0xfd, 0xdd, 0x72, 0x9a, 0x27,
|
|
||||||
0x33, 0x3a, 0xc5, 0x9e, 0x90, 0xb0, 0xd8, 0xbd, 0x23, 0x0e, 0x7f, 0xd3, 0xfc, 0x1f, 0x7e, 0x33,
|
|
||||||
0x59, 0x3f, 0xbc, 0xdc, 0xb7, 0xbd, 0xef, 0x82, 0x2a, 0x1b, 0x67, 0xe4, 0xab, 0xeb, 0x6a, 0xab,
|
|
||||||
0xa8, 0xb6, 0xba, 0x73, 0xc4, 0x5e, 0x8e, 0x35, 0x9b, 0x6b, 0xfc, 0x1c, 0x90, 0x7a, 0x83, 0xd6,
|
|
||||||
0xb3, 0x6c, 0x69, 0x68, 0xe4, 0xf7, 0x27, 0x31, 0xd2, 0x07, 0x92, 0x9a, 0x27, 0x75, 0xf7, 0x15,
|
|
||||||
0x00, 0x00, 0xff, 0xff, 0x75, 0x28, 0x26, 0x8f, 0x3b, 0x01, 0x00, 0x00,
|
|
||||||
}
|
|
@ -1,7 +1,7 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// source: proto/web.proto
|
// source: proto/web.proto
|
||||||
|
|
||||||
package server // import "github.com/johanbrandhorst/wasm-experiments/grpc/proto/server"
|
package web // import "github.com/johanbrandhorst/wasm-experiments/grpc/proto"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Web exposes a backend server over gRPC.
|
Web exposes a backend server over gRPC.
|
||||||
@ -38,7 +38,7 @@ func (m *GetUserRequest) Reset() { *m = GetUserRequest{} }
|
|||||||
func (m *GetUserRequest) String() string { return proto.CompactTextString(m) }
|
func (m *GetUserRequest) String() string { return proto.CompactTextString(m) }
|
||||||
func (*GetUserRequest) ProtoMessage() {}
|
func (*GetUserRequest) ProtoMessage() {}
|
||||||
func (*GetUserRequest) Descriptor() ([]byte, []int) {
|
func (*GetUserRequest) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_web_87670d45010119fa, []int{0}
|
return fileDescriptor_web_fab68bbab7573337, []int{0}
|
||||||
}
|
}
|
||||||
func (m *GetUserRequest) XXX_Unmarshal(b []byte) error {
|
func (m *GetUserRequest) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_GetUserRequest.Unmarshal(m, b)
|
return xxx_messageInfo_GetUserRequest.Unmarshal(m, b)
|
||||||
@ -76,7 +76,7 @@ func (m *User) Reset() { *m = User{} }
|
|||||||
func (m *User) String() string { return proto.CompactTextString(m) }
|
func (m *User) String() string { return proto.CompactTextString(m) }
|
||||||
func (*User) ProtoMessage() {}
|
func (*User) ProtoMessage() {}
|
||||||
func (*User) Descriptor() ([]byte, []int) {
|
func (*User) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_web_87670d45010119fa, []int{1}
|
return fileDescriptor_web_fab68bbab7573337, []int{1}
|
||||||
}
|
}
|
||||||
func (m *User) XXX_Unmarshal(b []byte) error {
|
func (m *User) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_User.Unmarshal(m, b)
|
return xxx_messageInfo_User.Unmarshal(m, b)
|
||||||
@ -114,7 +114,7 @@ func (m *GetUsersRequest) Reset() { *m = GetUsersRequest{} }
|
|||||||
func (m *GetUsersRequest) String() string { return proto.CompactTextString(m) }
|
func (m *GetUsersRequest) String() string { return proto.CompactTextString(m) }
|
||||||
func (*GetUsersRequest) ProtoMessage() {}
|
func (*GetUsersRequest) ProtoMessage() {}
|
||||||
func (*GetUsersRequest) Descriptor() ([]byte, []int) {
|
func (*GetUsersRequest) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_web_87670d45010119fa, []int{2}
|
return fileDescriptor_web_fab68bbab7573337, []int{2}
|
||||||
}
|
}
|
||||||
func (m *GetUsersRequest) XXX_Unmarshal(b []byte) error {
|
func (m *GetUsersRequest) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_GetUsersRequest.Unmarshal(m, b)
|
return xxx_messageInfo_GetUsersRequest.Unmarshal(m, b)
|
||||||
@ -280,23 +280,23 @@ var _Backend_serviceDesc = grpc.ServiceDesc{
|
|||||||
Metadata: "proto/web.proto",
|
Metadata: "proto/web.proto",
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { proto.RegisterFile("proto/web.proto", fileDescriptor_web_87670d45010119fa) }
|
func init() { proto.RegisterFile("proto/web.proto", fileDescriptor_web_fab68bbab7573337) }
|
||||||
|
|
||||||
var fileDescriptor_web_87670d45010119fa = []byte{
|
var fileDescriptor_web_fab68bbab7573337 = []byte{
|
||||||
// 236 bytes of a gzipped FileDescriptorProto
|
// 235 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0xc1, 0x4b, 0xc3, 0x30,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0xb1, 0x4b, 0xc4, 0x30,
|
||||||
0x18, 0xc5, 0xdd, 0x26, 0xeb, 0xfa, 0x1d, 0x36, 0x88, 0xa2, 0xa2, 0x17, 0xe9, 0x49, 0x11, 0x1b,
|
0x18, 0xc5, 0xed, 0x9d, 0x5c, 0xaf, 0xdf, 0x70, 0x07, 0x51, 0x54, 0x74, 0x91, 0x4e, 0x8a, 0xd8,
|
||||||
0xd1, 0xb3, 0x08, 0xbb, 0x88, 0xd7, 0x82, 0x17, 0x2f, 0xa3, 0x69, 0x3e, 0xda, 0x2a, 0x49, 0xea,
|
0x88, 0x6e, 0xea, 0x74, 0x8b, 0xb8, 0x16, 0x5c, 0x5c, 0x8e, 0xa6, 0xf9, 0x68, 0xab, 0x24, 0xa9,
|
||||||
0xf7, 0x25, 0xd6, 0x3f, 0x5f, 0x12, 0x37, 0x51, 0xf0, 0x96, 0xf7, 0xf2, 0x7b, 0x2f, 0x8f, 0xc0,
|
0xf9, 0x12, 0xe2, 0x9f, 0x2f, 0x09, 0x57, 0x51, 0xb8, 0xed, 0xe5, 0xe5, 0xf7, 0x5e, 0x1e, 0x81,
|
||||||
0x6a, 0x20, 0xe7, 0x9d, 0x1c, 0x51, 0x95, 0xe9, 0x24, 0x66, 0x23, 0xaa, 0xe2, 0x12, 0x96, 0x8f,
|
0xf5, 0x68, 0x8d, 0x33, 0x3c, 0xa0, 0xa8, 0x92, 0x62, 0xf3, 0x80, 0xa2, 0xbc, 0x86, 0xd5, 0x0b,
|
||||||
0xe8, 0x9f, 0x19, 0xa9, 0xc2, 0xf7, 0x80, 0xec, 0xc5, 0x31, 0x64, 0x81, 0x91, 0x36, 0xbd, 0x3e,
|
0xba, 0x37, 0x42, 0x5b, 0xe3, 0x97, 0x47, 0x72, 0xec, 0x14, 0x72, 0x4f, 0x68, 0xb7, 0x83, 0x3c,
|
||||||
0x99, 0x9c, 0x4f, 0x2e, 0xf2, 0x6a, 0x1e, 0xe5, 0x93, 0x2e, 0x8e, 0x60, 0x3f, 0x72, 0x62, 0x09,
|
0xcb, 0x2e, 0xb3, 0xab, 0xa2, 0x5e, 0xc4, 0xe3, 0xab, 0x2c, 0x4f, 0xe0, 0x30, 0x72, 0x6c, 0x05,
|
||||||
0xd3, 0x9f, 0xbb, 0x69, 0xaf, 0x8b, 0x12, 0x56, 0xdb, 0x0a, 0xde, 0x75, 0x9c, 0x41, 0x6e, 0x83,
|
0xb3, 0xdf, 0xbb, 0xd9, 0x20, 0xcb, 0x0a, 0xd6, 0xbb, 0x0a, 0x9a, 0x3a, 0x2e, 0xa0, 0xd0, 0x5e,
|
||||||
0xd9, 0xc4, 0x20, 0x27, 0x72, 0x56, 0x2d, 0x6c, 0x30, 0x89, 0xb9, 0x6d, 0x21, 0x5b, 0xd7, 0xcd,
|
0x6d, 0x63, 0x90, 0x12, 0x39, 0xaf, 0x97, 0xda, 0xab, 0xc4, 0xdc, 0x77, 0x90, 0x6f, 0x9a, 0xf6,
|
||||||
0x1b, 0x5a, 0x2d, 0xae, 0x20, 0xdb, 0x46, 0xc5, 0x41, 0x19, 0x97, 0xfd, 0xdd, 0x72, 0x9a, 0x27,
|
0x13, 0xb5, 0x64, 0x37, 0x90, 0xef, 0xa2, 0xec, 0xa8, 0x8a, 0xcb, 0xfe, 0x6f, 0x39, 0x2f, 0x92,
|
||||||
0x33, 0x3a, 0xc5, 0x9e, 0x90, 0xb0, 0xd8, 0xbd, 0x23, 0x0e, 0x7f, 0xd3, 0xfc, 0x1f, 0x7e, 0x33,
|
0x19, 0x9d, 0xf2, 0x80, 0x71, 0x58, 0x4e, 0xef, 0xb0, 0xe3, 0xbf, 0x34, 0xed, 0xc3, 0xef, 0xb2,
|
||||||
0x59, 0x3f, 0xbc, 0xdc, 0xb7, 0xbd, 0xef, 0x82, 0x2a, 0x1b, 0x67, 0xe4, 0xab, 0xeb, 0x6a, 0xab,
|
0xcd, 0xf3, 0xfb, 0x63, 0x37, 0xb8, 0xde, 0x8b, 0xaa, 0x35, 0x8a, 0x7f, 0x98, 0xbe, 0xd1, 0xc2,
|
||||||
0xa8, 0xb6, 0xba, 0x73, 0xc4, 0x5e, 0x8e, 0x35, 0x9b, 0x6b, 0xfc, 0x1c, 0x90, 0x7a, 0x83, 0xd6,
|
0x36, 0x5a, 0xf6, 0xc6, 0x92, 0xe3, 0xa1, 0x21, 0x75, 0x8b, 0xdf, 0x23, 0xda, 0x41, 0xa1, 0x76,
|
||||||
0xb3, 0x6c, 0x69, 0x68, 0xe4, 0xf7, 0x27, 0x31, 0xd2, 0x07, 0x92, 0x9a, 0x27, 0x75, 0xf7, 0x15,
|
0xc4, 0x3b, 0x3b, 0xb6, 0x3c, 0x7d, 0xcd, 0x53, 0x40, 0x21, 0x16, 0x49, 0x3e, 0xfc, 0x04, 0x00,
|
||||||
0x00, 0x00, 0xff, 0xff, 0x75, 0x28, 0x26, 0x8f, 0x3b, 0x01, 0x00, 0x00,
|
0x00, 0xff, 0xff, 0xaf, 0xf7, 0xf4, 0x4f, 0x38, 0x01, 0x00, 0x00,
|
||||||
}
|
}
|
@ -3,7 +3,7 @@ syntax = "proto3";
|
|||||||
// Web exposes a backend server over gRPC.
|
// Web exposes a backend server over gRPC.
|
||||||
package web;
|
package web;
|
||||||
|
|
||||||
option go_package = "github.com/johanbrandhorst/wasm-experiments/grpc/proto/server";
|
option go_package = "github.com/johanbrandhorst/wasm-experiments/grpc/proto;web";
|
||||||
|
|
||||||
// Backend defines the interface exposed by the backend.
|
// Backend defines the interface exposed by the backend.
|
||||||
service Backend {
|
service Backend {
|
||||||
|
7
vendor/github.com/improbable-eng/grpc-web/go/grpcweb/grpc_web_response.go
generated
vendored
7
vendor/github.com/improbable-eng/grpc-web/go/grpcweb/grpc_web_response.go
generated
vendored
@ -90,6 +90,7 @@ func (w *grpcWebResponse) copyTrailersAndHeadersToWrapped() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.writeCorsExposedHeaders()
|
w.writeCorsExposedHeaders()
|
||||||
|
hackIntogRPCWebContentType(wrappedHeader)
|
||||||
w.wrapped.WriteHeader(http.StatusOK)
|
w.wrapped.WriteHeader(http.StatusOK)
|
||||||
w.wrapped.(http.Flusher).Flush()
|
w.wrapped.(http.Flusher).Flush()
|
||||||
}
|
}
|
||||||
@ -134,5 +135,11 @@ func (w *grpcWebResponse) extractTrailerHeaders() http.Header {
|
|||||||
trailerHeaders.Add(k, v)
|
trailerHeaders.Add(k, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
hackIntogRPCWebContentType(trailerHeaders)
|
||||||
return trailerHeaders
|
return trailerHeaders
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func hackIntogRPCWebContentType(in http.Header) {
|
||||||
|
contentType := in.Get("content-type")
|
||||||
|
in.Set("content-type", strings.Replace(contentType, "application/grpc", "application/grpc-web", 1))
|
||||||
|
}
|
||||||
|
1
vendor/github.com/johanbrandhorst/grpc-wasm/.gitignore
generated
vendored
1
vendor/github.com/johanbrandhorst/grpc-wasm/.gitignore
generated
vendored
@ -1 +0,0 @@
|
|||||||
.vscode
|
|
5
vendor/github.com/johanbrandhorst/grpc-wasm/Makefile
generated
vendored
5
vendor/github.com/johanbrandhorst/grpc-wasm/Makefile
generated
vendored
@ -1,5 +0,0 @@
|
|||||||
update-plugin:
|
|
||||||
# https://stackoverflow.com/a/39317180
|
|
||||||
svn export https://github.com/golang/protobuf/trunk/protoc-gen-go
|
|
||||||
rm -rf protoc-gen-wasm
|
|
||||||
mv protoc-gen-go protoc-gen-wasm
|
|
2
vendor/github.com/johanbrandhorst/grpc-wasm/README.md
generated
vendored
2
vendor/github.com/johanbrandhorst/grpc-wasm/README.md
generated
vendored
@ -1,2 +0,0 @@
|
|||||||
# gRPC-WASM
|
|
||||||
gRPC-Web implementation in Go. Built as a drop-in alternative to google.golang.org/grpc.
|
|
22
vendor/github.com/johanbrandhorst/grpc-wasm/calloptions.go
generated
vendored
22
vendor/github.com/johanbrandhorst/grpc-wasm/calloptions.go
generated
vendored
@ -1,22 +0,0 @@
|
|||||||
// +build js,wasm
|
|
||||||
|
|
||||||
package grpc
|
|
||||||
|
|
||||||
// CallOption configures a Call before it starts or extracts information from
|
|
||||||
// a Call after it completes.
|
|
||||||
type CallOption interface {
|
|
||||||
// before is called before the call is sent to any server. If before
|
|
||||||
// returns a non-nil error, the RPC fails with that error.
|
|
||||||
before(*callInfo) error
|
|
||||||
|
|
||||||
// after is called after the call has completed. after cannot return an
|
|
||||||
// error, so any failures should be reported via output parameters.
|
|
||||||
after(*callInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
type callInfo struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func defaultCallInfo() *callInfo {
|
|
||||||
return &callInfo{}
|
|
||||||
}
|
|
234
vendor/github.com/johanbrandhorst/grpc-wasm/clientconn.go
generated
vendored
234
vendor/github.com/johanbrandhorst/grpc-wasm/clientconn.go
generated
vendored
@ -1,234 +0,0 @@
|
|||||||
// +build js,wasm
|
|
||||||
|
|
||||||
package grpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"bytes"
|
|
||||||
"context"
|
|
||||||
"encoding/base64"
|
|
||||||
"encoding/binary"
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/golang/protobuf/proto"
|
|
||||||
spb "google.golang.org/genproto/googleapis/rpc/status"
|
|
||||||
"google.golang.org/grpc/codes"
|
|
||||||
"google.golang.org/grpc/metadata"
|
|
||||||
"google.golang.org/grpc/status"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ClientConn struct {
|
|
||||||
target string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dial creates a client connection to the target. The target string should
|
|
||||||
// be a URL with scheme HTTP or HTTPS, or a FQDN to infer the scheme.
|
|
||||||
func Dial(target string, opts ...DialOption) (*ClientConn, error) {
|
|
||||||
return DialContext(context.Background(), target, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *ClientConn, err error) {
|
|
||||||
return &ClientConn{
|
|
||||||
target: target,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cc *ClientConn) NewStream(ctx context.Context, desc *StreamDesc, method string, opts ...CallOption) (ClientStream, error) {
|
|
||||||
if desc.ClientStreams {
|
|
||||||
return nil, status.Error(codes.Unimplemented, "client-side streaming is not supported by grpc-web")
|
|
||||||
}
|
|
||||||
|
|
||||||
endpoint := cc.target + "/" + method
|
|
||||||
if cc.target == "" {
|
|
||||||
endpoint = method
|
|
||||||
}
|
|
||||||
|
|
||||||
return newStream(ctx, endpoint)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cc *ClientConn) Invoke(ctx context.Context, method string, args, reply interface{}, opts ...CallOption) error {
|
|
||||||
b, err := proto.Marshal(args.(proto.Message))
|
|
||||||
if err != nil {
|
|
||||||
return status.Error(codes.Internal, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
bufHeader := make([]byte, 5)
|
|
||||||
|
|
||||||
// Write length of b into buf
|
|
||||||
binary.BigEndian.PutUint32(bufHeader[1:], uint32(len(b)))
|
|
||||||
|
|
||||||
endpoint := cc.target + "/" + method
|
|
||||||
if cc.target == "" {
|
|
||||||
endpoint = method
|
|
||||||
}
|
|
||||||
req, err := http.NewRequest(
|
|
||||||
"POST",
|
|
||||||
endpoint,
|
|
||||||
bytes.NewBuffer(append(bufHeader, b...)),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return status.Error(codes.Unavailable, err.Error())
|
|
||||||
}
|
|
||||||
req = req.WithContext(ctx)
|
|
||||||
addHeaders(req)
|
|
||||||
|
|
||||||
resp, err := http.DefaultClient.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return status.Error(codes.Internal, err.Error())
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
st := statusFromHeaders(resp.Header)
|
|
||||||
if st.Code() != codes.OK {
|
|
||||||
return st.Err()
|
|
||||||
}
|
|
||||||
|
|
||||||
msgHeader := make([]byte, 5)
|
|
||||||
for {
|
|
||||||
_, err := resp.Body.Read(msgHeader)
|
|
||||||
if err != nil {
|
|
||||||
return status.Error(codes.Internal, err.Error())
|
|
||||||
}
|
|
||||||
// 1 in MSB signifies that this is the trailer. Break loop.
|
|
||||||
// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md#protocol-differences-vs-grpc-over-http2
|
|
||||||
if msgHeader[0]>>7 == 1 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
msgLen := binary.BigEndian.Uint32(msgHeader[1:])
|
|
||||||
|
|
||||||
msg := make([]byte, msgLen)
|
|
||||||
_, err = resp.Body.Read(msg)
|
|
||||||
if err != nil {
|
|
||||||
return status.Error(codes.Internal, err.Error())
|
|
||||||
}
|
|
||||||
err = proto.Unmarshal(msg, reply.(proto.Message))
|
|
||||||
if err != nil {
|
|
||||||
return status.Error(codes.Internal, err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if msgHeader[0]&1 == 0 {
|
|
||||||
trailers, err := readTrailers(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return status.Error(codes.Internal, err.Error())
|
|
||||||
}
|
|
||||||
st = statusFromHeaders(trailers)
|
|
||||||
} else {
|
|
||||||
// TODO(johanbrandhorst): Support compressed trailers
|
|
||||||
}
|
|
||||||
|
|
||||||
return st.Err()
|
|
||||||
}
|
|
||||||
|
|
||||||
func addHeaders(req *http.Request) {
|
|
||||||
// TODO: Add more headers
|
|
||||||
// https://github.com/grpc/grpc-go/blob/590da37e2dfb4705d8ebd9574ce4cb75295d9674/transport/http2_client.go#L356
|
|
||||||
req.Header.Add("content-type", "application/grpc-web+proto")
|
|
||||||
req.Header.Add("x-grpc-web", "1")
|
|
||||||
if dl, ok := req.Context().Deadline(); ok {
|
|
||||||
timeout := dl.Sub(time.Now())
|
|
||||||
req.Header.Add("grpc-timeout", encodeTimeout(timeout))
|
|
||||||
}
|
|
||||||
md, ok := metadata.FromOutgoingContext(req.Context())
|
|
||||||
if ok {
|
|
||||||
for h, vs := range md {
|
|
||||||
for _, v := range vs {
|
|
||||||
req.Header.Add(h, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const maxTimeoutValue int64 = 100000000 - 1
|
|
||||||
|
|
||||||
// Copied from grpc-go
|
|
||||||
// https://github.com/grpc/grpc-go/blob/590da37e2dfb4705d8ebd9574ce4cb75295d9674/transport/http_util.go#L388
|
|
||||||
// div does integer division and round-up the result. Note that this is
|
|
||||||
// equivalent to (d+r-1)/r but has less chance to overflow.
|
|
||||||
func div(d, r time.Duration) int64 {
|
|
||||||
if m := d % r; m > 0 {
|
|
||||||
return int64(d/r + 1)
|
|
||||||
}
|
|
||||||
return int64(d / r)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copied from grpc-go
|
|
||||||
// https://github.com/grpc/grpc-go/blob/590da37e2dfb4705d8ebd9574ce4cb75295d9674/transport/http_util.go#L398
|
|
||||||
func encodeTimeout(t time.Duration) string {
|
|
||||||
if t <= 0 {
|
|
||||||
return "0n"
|
|
||||||
}
|
|
||||||
if d := div(t, time.Nanosecond); d <= maxTimeoutValue {
|
|
||||||
return strconv.FormatInt(d, 10) + "n"
|
|
||||||
}
|
|
||||||
if d := div(t, time.Microsecond); d <= maxTimeoutValue {
|
|
||||||
return strconv.FormatInt(d, 10) + "u"
|
|
||||||
}
|
|
||||||
if d := div(t, time.Millisecond); d <= maxTimeoutValue {
|
|
||||||
return strconv.FormatInt(d, 10) + "m"
|
|
||||||
}
|
|
||||||
if d := div(t, time.Second); d <= maxTimeoutValue {
|
|
||||||
return strconv.FormatInt(d, 10) + "S"
|
|
||||||
}
|
|
||||||
if d := div(t, time.Minute); d <= maxTimeoutValue {
|
|
||||||
return strconv.FormatInt(d, 10) + "M"
|
|
||||||
}
|
|
||||||
// Note that maxTimeoutValue * time.Hour > MaxInt64.
|
|
||||||
return strconv.FormatInt(div(t, time.Hour), 10) + "H"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copied from grpc-go
|
|
||||||
// https://github.com/grpc/grpc-go/blob/b94ea975f3beb73799fac17cc24ee923fcd3cb5c/transport/http_util.go#L213
|
|
||||||
func decodeBinHeader(v string) ([]byte, error) {
|
|
||||||
if len(v)%4 == 0 {
|
|
||||||
// Input was padded, or padding was not necessary.
|
|
||||||
return base64.StdEncoding.DecodeString(v)
|
|
||||||
}
|
|
||||||
return base64.RawStdEncoding.DecodeString(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
func readTrailers(in io.Reader) (http.Header, error) {
|
|
||||||
s := bufio.NewScanner(in)
|
|
||||||
trailers := http.Header{}
|
|
||||||
for s.Scan() {
|
|
||||||
v := s.Text()
|
|
||||||
kv := strings.SplitN(v, ": ", 2)
|
|
||||||
if len(kv) != 2 {
|
|
||||||
return nil, errors.New("malformed header: " + v)
|
|
||||||
}
|
|
||||||
trailers.Add(kv[0], kv[1])
|
|
||||||
}
|
|
||||||
|
|
||||||
return trailers, s.Err()
|
|
||||||
}
|
|
||||||
|
|
||||||
func statusFromHeaders(h http.Header) *status.Status {
|
|
||||||
details := h.Get("grpc-status-details-bin")
|
|
||||||
if details != "" {
|
|
||||||
b, err := decodeBinHeader(details)
|
|
||||||
if err != nil {
|
|
||||||
return status.New(codes.Internal, "malformed grps-status-details-bin header: "+err.Error())
|
|
||||||
}
|
|
||||||
s := &spb.Status{}
|
|
||||||
err = proto.Unmarshal(b, s)
|
|
||||||
if err != nil {
|
|
||||||
return status.New(codes.Internal, "malformed grps-status-details-bin header: "+err.Error())
|
|
||||||
}
|
|
||||||
return status.FromProto(s)
|
|
||||||
}
|
|
||||||
sh := h.Get("grpc-status")
|
|
||||||
if sh != "" {
|
|
||||||
val, err := strconv.Atoi(sh)
|
|
||||||
if err != nil {
|
|
||||||
return status.New(codes.Internal, "malformed grpc-status header: "+err.Error())
|
|
||||||
}
|
|
||||||
return status.New(codes.Code(val), h.Get("grpc-message"))
|
|
||||||
}
|
|
||||||
return status.New(codes.OK, "")
|
|
||||||
}
|
|
194
vendor/github.com/johanbrandhorst/grpc-wasm/clientstream.go
generated
vendored
194
vendor/github.com/johanbrandhorst/grpc-wasm/clientstream.go
generated
vendored
@ -1,194 +0,0 @@
|
|||||||
// +build js,wasm
|
|
||||||
|
|
||||||
package grpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"context"
|
|
||||||
"encoding/binary"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/golang/protobuf/proto"
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
"google.golang.org/grpc/codes"
|
|
||||||
"google.golang.org/grpc/metadata"
|
|
||||||
"google.golang.org/grpc/status"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ClientStream defines the interface a client stream has to satisfy.
|
|
||||||
type ClientStream grpc.ClientStream
|
|
||||||
|
|
||||||
// ServerStream defines the interface a server stream has to satisfy.
|
|
||||||
type ServerStream grpc.ServerStream
|
|
||||||
|
|
||||||
// StreamHandler defines the handler called by gRPC server to complete the
|
|
||||||
// execution of a streaming RPC. If a StreamHandler returns an error, it
|
|
||||||
// should be produced by the status package, or else gRPC will use
|
|
||||||
// codes.Unknown as the status code and err.Error() as the status message
|
|
||||||
// of the RPC.
|
|
||||||
type StreamHandler func(srv interface{}, stream ServerStream) error
|
|
||||||
|
|
||||||
// StreamDesc represents a streaming RPC service's method specification.
|
|
||||||
type StreamDesc struct {
|
|
||||||
StreamName string
|
|
||||||
Handler StreamHandler
|
|
||||||
|
|
||||||
// At least one of these is true.
|
|
||||||
ServerStreams bool
|
|
||||||
ClientStreams bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type methodHandler func(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor UnaryServerInterceptor) (interface{}, error)
|
|
||||||
|
|
||||||
// MethodDesc represents an RPC service's method specification.
|
|
||||||
type MethodDesc struct {
|
|
||||||
MethodName string
|
|
||||||
Handler methodHandler
|
|
||||||
}
|
|
||||||
|
|
||||||
// ServiceDesc represents an RPC service's specification.
|
|
||||||
type ServiceDesc struct {
|
|
||||||
ServiceName string
|
|
||||||
// The pointer to the service interface. Used to check whether the user
|
|
||||||
// provided implementation satisfies the interface requirements.
|
|
||||||
HandlerType interface{}
|
|
||||||
Methods []MethodDesc
|
|
||||||
Streams []StreamDesc
|
|
||||||
Metadata interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
type clientStream struct {
|
|
||||||
ctx context.Context
|
|
||||||
req *http.Request
|
|
||||||
errCh chan error
|
|
||||||
msgCh chan []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func newStream(ctx context.Context, endpoint string) (*clientStream, error) {
|
|
||||||
cs := &clientStream{
|
|
||||||
ctx: ctx,
|
|
||||||
}
|
|
||||||
|
|
||||||
req, err := http.NewRequest(
|
|
||||||
"POST",
|
|
||||||
endpoint,
|
|
||||||
nil,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, status.New(codes.Unavailable, err.Error()).Err()
|
|
||||||
}
|
|
||||||
|
|
||||||
cs.req = req.WithContext(ctx)
|
|
||||||
return cs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *clientStream) Header() (metadata.MD, error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *clientStream) Trailer() metadata.MD {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *clientStream) Context() context.Context {
|
|
||||||
return c.ctx
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *clientStream) RecvMsg(reply interface{}) error {
|
|
||||||
select {
|
|
||||||
case <-c.ctx.Done():
|
|
||||||
return c.ctx.Err()
|
|
||||||
case err := <-c.errCh:
|
|
||||||
return err
|
|
||||||
case msg, ok := <-c.msgCh:
|
|
||||||
if !ok {
|
|
||||||
return io.EOF
|
|
||||||
}
|
|
||||||
err := proto.Unmarshal(msg, reply.(proto.Message))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *clientStream) SendMsg(req interface{}) error {
|
|
||||||
msg, err := proto.Marshal(req.(proto.Message))
|
|
||||||
if err != nil {
|
|
||||||
return status.Error(codes.Internal, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
bufHeader := make([]byte, 5)
|
|
||||||
|
|
||||||
// Write length of b into buf
|
|
||||||
binary.BigEndian.PutUint32(bufHeader[1:], uint32(len(msg)))
|
|
||||||
|
|
||||||
c.req.Body = ioutil.NopCloser(bytes.NewBuffer(append(bufHeader, msg...)))
|
|
||||||
addHeaders(c.req)
|
|
||||||
|
|
||||||
resp, err := http.DefaultClient.Do(c.req)
|
|
||||||
if err != nil {
|
|
||||||
return status.Error(codes.Unavailable, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
st := statusFromHeaders(resp.Header)
|
|
||||||
if st.Code() != codes.OK {
|
|
||||||
resp.Body.Close()
|
|
||||||
return st.Err()
|
|
||||||
}
|
|
||||||
|
|
||||||
c.errCh = make(chan error, 1)
|
|
||||||
c.msgCh = make(chan []byte, 1)
|
|
||||||
|
|
||||||
// Read response asynchronously
|
|
||||||
go func() {
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
msgHeader := make([]byte, 5)
|
|
||||||
for {
|
|
||||||
_, err := io.ReadFull(resp.Body, msgHeader)
|
|
||||||
if err != nil {
|
|
||||||
c.errCh <- status.Error(codes.Internal, err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// 1 in MSB signifies that this is the trailer. Break loop.
|
|
||||||
// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md#protocol-differences-vs-grpc-over-http2
|
|
||||||
if msgHeader[0]>>7 == 1 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
msgLen := binary.BigEndian.Uint32(msgHeader[1:])
|
|
||||||
|
|
||||||
msg := make([]byte, msgLen)
|
|
||||||
_, err = io.ReadFull(resp.Body, msg)
|
|
||||||
if err != nil {
|
|
||||||
c.errCh <- status.Error(codes.Internal, err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.msgCh <- msg
|
|
||||||
}
|
|
||||||
|
|
||||||
if msgHeader[0]&1 == 0 {
|
|
||||||
trailers, err := readTrailers(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
c.errCh <- status.Error(codes.Internal, err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
st = statusFromHeaders(trailers)
|
|
||||||
} else {
|
|
||||||
// TODO(johanbrandhorst): Support compressed trailers
|
|
||||||
}
|
|
||||||
|
|
||||||
if st.Code() != codes.OK {
|
|
||||||
c.errCh <- st.Err()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
close(c.msgCh)
|
|
||||||
}()
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *clientStream) CloseSend() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
11
vendor/github.com/johanbrandhorst/grpc-wasm/dialoptions.go
generated
vendored
11
vendor/github.com/johanbrandhorst/grpc-wasm/dialoptions.go
generated
vendored
@ -1,11 +0,0 @@
|
|||||||
// +build js,wasm
|
|
||||||
|
|
||||||
package grpc
|
|
||||||
|
|
||||||
// DialOption configures how we set up the connection.
|
|
||||||
type DialOption func(*dialOptions)
|
|
||||||
|
|
||||||
// dialOptions configure a Dial call. dialOptions are set by the DialOption
|
|
||||||
// values passed to Dial.
|
|
||||||
type dialOptions struct {
|
|
||||||
}
|
|
17
vendor/github.com/johanbrandhorst/grpc-wasm/doc.go
generated
vendored
17
vendor/github.com/johanbrandhorst/grpc-wasm/doc.go
generated
vendored
@ -1,17 +0,0 @@
|
|||||||
// +build js,wasm
|
|
||||||
|
|
||||||
package grpc
|
|
||||||
|
|
||||||
// The SupportPackageIsVersion variables are referenced from generated protocol
|
|
||||||
// buffer files to ensure compatibility with the gRPC version used. The latest
|
|
||||||
// support package version is 4.
|
|
||||||
//
|
|
||||||
// Older versions are kept for compatibility. They may be removed if
|
|
||||||
// compatibility cannot be maintained.
|
|
||||||
//
|
|
||||||
// These constants should not be referenced from any other code.
|
|
||||||
//
|
|
||||||
// Note: grpc-wasm is compatible with Version4+ files only.
|
|
||||||
const (
|
|
||||||
SupportPackageIsVersion4 = true
|
|
||||||
)
|
|
26
vendor/github.com/johanbrandhorst/grpc-wasm/interceptor.go
generated
vendored
26
vendor/github.com/johanbrandhorst/grpc-wasm/interceptor.go
generated
vendored
@ -1,26 +0,0 @@
|
|||||||
// +build js,wasm
|
|
||||||
|
|
||||||
package grpc
|
|
||||||
|
|
||||||
import "context"
|
|
||||||
|
|
||||||
// UnaryServerInfo consists of various information about a unary RPC on
|
|
||||||
// server side. All per-rpc information may be mutated by the interceptor.
|
|
||||||
type UnaryServerInfo struct {
|
|
||||||
// Server is the service implementation the user provides. This is read-only.
|
|
||||||
Server interface{}
|
|
||||||
// FullMethod is the full RPC method string, i.e., /package.service/method.
|
|
||||||
FullMethod string
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnaryHandler defines the handler invoked by UnaryServerInterceptor to complete the normal
|
|
||||||
// execution of a unary RPC. If a UnaryHandler returns an error, it should be produced by the
|
|
||||||
// status package, or else gRPC will use codes.Unknown as the status code and err.Error() as
|
|
||||||
// the status message of the RPC.
|
|
||||||
type UnaryHandler func(ctx context.Context, req interface{}) (interface{}, error)
|
|
||||||
|
|
||||||
// UnaryServerInterceptor provides a hook to intercept the execution of a unary RPC on the server. info
|
|
||||||
// contains all the information of this RPC the interceptor can operate on. And handler is the wrapper
|
|
||||||
// of the service method implementation. It is the responsibility of the interceptor to invoke handler
|
|
||||||
// to complete the RPC.
|
|
||||||
type UnaryServerInterceptor func(ctx context.Context, req interface{}, info *UnaryServerInfo, handler UnaryHandler) (resp interface{}, err error)
|
|
8
vendor/github.com/johanbrandhorst/grpc-wasm/server.go
generated
vendored
8
vendor/github.com/johanbrandhorst/grpc-wasm/server.go
generated
vendored
@ -1,8 +0,0 @@
|
|||||||
// +build js,wasm
|
|
||||||
|
|
||||||
package grpc
|
|
||||||
|
|
||||||
// Server is a gRPC server to serve RPC requests.
|
|
||||||
type Server struct{}
|
|
||||||
|
|
||||||
func (s *Server) RegisterService(sd *ServiceDesc, ss interface{}) {}
|
|
5
vendor/google.golang.org/grpc/.travis.yml
generated
vendored
5
vendor/google.golang.org/grpc/.travis.yml
generated
vendored
@ -11,14 +11,19 @@ matrix:
|
|||||||
include:
|
include:
|
||||||
- go: 1.10.x
|
- go: 1.10.x
|
||||||
env: RUN386=1
|
env: RUN386=1
|
||||||
|
- go: 1.9.x
|
||||||
|
env: GAE=1
|
||||||
|
|
||||||
|
|
||||||
go_import_path: google.golang.org/grpc
|
go_import_path: google.golang.org/grpc
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- if [[ -n "$RUN386" ]]; then export GOARCH=386; fi
|
- if [[ -n "$RUN386" ]]; then export GOARCH=386; fi
|
||||||
- if [[ "$TRAVIS_GO_VERSION" = 1.10* && "$GOARCH" != "386" ]]; then ./vet.sh -install || exit 1; fi
|
- if [[ "$TRAVIS_GO_VERSION" = 1.10* && "$GOARCH" != "386" ]]; then ./vet.sh -install || exit 1; fi
|
||||||
|
- if [[ "$GAE" = 1 ]]; then source ./install_gae.sh || exit 1; fi
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- if [[ "$TRAVIS_GO_VERSION" = 1.10* && "$GOARCH" != "386" ]]; then ./vet.sh || exit 1; fi
|
- if [[ "$TRAVIS_GO_VERSION" = 1.10* && "$GOARCH" != "386" ]]; then ./vet.sh || exit 1; fi
|
||||||
|
- if [[ "$GAE" = 1 ]]; then make testappengine || exit 1; exit 0; fi
|
||||||
- make test || exit 1
|
- make test || exit 1
|
||||||
- if [[ "$GOARCH" != "386" ]]; then make testrace; fi
|
- if [[ "$GOARCH" != "386" ]]; then make testrace; fi
|
||||||
|
7
vendor/google.golang.org/grpc/Makefile
generated
vendored
7
vendor/google.golang.org/grpc/Makefile
generated
vendored
@ -9,6 +9,9 @@ updatedeps:
|
|||||||
testdeps:
|
testdeps:
|
||||||
go get -d -v -t google.golang.org/grpc/...
|
go get -d -v -t google.golang.org/grpc/...
|
||||||
|
|
||||||
|
testgaedeps:
|
||||||
|
goapp get -d -v -t -tags 'appengine appenginevm' google.golang.org/grpc/...
|
||||||
|
|
||||||
updatetestdeps:
|
updatetestdeps:
|
||||||
go get -d -v -t -u -f google.golang.org/grpc/...
|
go get -d -v -t -u -f google.golang.org/grpc/...
|
||||||
|
|
||||||
@ -31,6 +34,9 @@ test: testdeps
|
|||||||
testrace: testdeps
|
testrace: testdeps
|
||||||
go test -race -cpu 1,4 -timeout 7m google.golang.org/grpc/...
|
go test -race -cpu 1,4 -timeout 7m google.golang.org/grpc/...
|
||||||
|
|
||||||
|
testappengine: testgaedeps
|
||||||
|
goapp test -cpu 1,4 -timeout 5m google.golang.org/grpc/...
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
go clean -i google.golang.org/grpc/...
|
go clean -i google.golang.org/grpc/...
|
||||||
|
|
||||||
@ -39,6 +45,7 @@ clean:
|
|||||||
deps \
|
deps \
|
||||||
updatedeps \
|
updatedeps \
|
||||||
testdeps \
|
testdeps \
|
||||||
|
testgaedeps \
|
||||||
updatetestdeps \
|
updatetestdeps \
|
||||||
build \
|
build \
|
||||||
proto \
|
proto \
|
||||||
|
66
vendor/google.golang.org/grpc/backoff.go
generated
vendored
66
vendor/google.golang.org/grpc/backoff.go
generated
vendored
@ -16,81 +16,23 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// See internal/backoff package for the backoff implementation. This file is
|
||||||
|
// kept for the exported types and API backward compatility.
|
||||||
|
|
||||||
package grpc
|
package grpc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/rand"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefaultBackoffConfig uses values specified for backoff in
|
// DefaultBackoffConfig uses values specified for backoff in
|
||||||
// https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md.
|
// https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md.
|
||||||
var DefaultBackoffConfig = BackoffConfig{
|
var DefaultBackoffConfig = BackoffConfig{
|
||||||
MaxDelay: 120 * time.Second,
|
MaxDelay: 120 * time.Second,
|
||||||
baseDelay: 1.0 * time.Second,
|
|
||||||
factor: 1.6,
|
|
||||||
jitter: 0.2,
|
|
||||||
}
|
|
||||||
|
|
||||||
// backoffStrategy defines the methodology for backing off after a grpc
|
|
||||||
// connection failure.
|
|
||||||
//
|
|
||||||
// This is unexported until the gRPC project decides whether or not to allow
|
|
||||||
// alternative backoff strategies. Once a decision is made, this type and its
|
|
||||||
// method may be exported.
|
|
||||||
type backoffStrategy interface {
|
|
||||||
// backoff returns the amount of time to wait before the next retry given
|
|
||||||
// the number of consecutive failures.
|
|
||||||
backoff(retries int) time.Duration
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// BackoffConfig defines the parameters for the default gRPC backoff strategy.
|
// BackoffConfig defines the parameters for the default gRPC backoff strategy.
|
||||||
type BackoffConfig struct {
|
type BackoffConfig struct {
|
||||||
// MaxDelay is the upper bound of backoff delay.
|
// MaxDelay is the upper bound of backoff delay.
|
||||||
MaxDelay time.Duration
|
MaxDelay time.Duration
|
||||||
|
|
||||||
// TODO(stevvooe): The following fields are not exported, as allowing
|
|
||||||
// changes would violate the current gRPC specification for backoff. If
|
|
||||||
// gRPC decides to allow more interesting backoff strategies, these fields
|
|
||||||
// may be opened up in the future.
|
|
||||||
|
|
||||||
// baseDelay is the amount of time to wait before retrying after the first
|
|
||||||
// failure.
|
|
||||||
baseDelay time.Duration
|
|
||||||
|
|
||||||
// factor is applied to the backoff after each retry.
|
|
||||||
factor float64
|
|
||||||
|
|
||||||
// jitter provides a range to randomize backoff delays.
|
|
||||||
jitter float64
|
|
||||||
}
|
|
||||||
|
|
||||||
func setDefaults(bc *BackoffConfig) {
|
|
||||||
md := bc.MaxDelay
|
|
||||||
*bc = DefaultBackoffConfig
|
|
||||||
|
|
||||||
if md > 0 {
|
|
||||||
bc.MaxDelay = md
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bc BackoffConfig) backoff(retries int) time.Duration {
|
|
||||||
if retries == 0 {
|
|
||||||
return bc.baseDelay
|
|
||||||
}
|
|
||||||
backoff, max := float64(bc.baseDelay), float64(bc.MaxDelay)
|
|
||||||
for backoff < max && retries > 0 {
|
|
||||||
backoff *= bc.factor
|
|
||||||
retries--
|
|
||||||
}
|
|
||||||
if backoff > max {
|
|
||||||
backoff = max
|
|
||||||
}
|
|
||||||
// Randomize backoff delays so that if a cluster of requests start at
|
|
||||||
// the same time, they won't operate in lockstep.
|
|
||||||
backoff *= 1 + bc.jitter*(rand.Float64()*2-1)
|
|
||||||
if backoff < 0 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return time.Duration(backoff)
|
|
||||||
}
|
}
|
||||||
|
42
vendor/google.golang.org/grpc/balancer/balancer.go
generated
vendored
42
vendor/google.golang.org/grpc/balancer/balancer.go
generated
vendored
@ -226,3 +226,45 @@ type Balancer interface {
|
|||||||
// ClientConn.RemoveSubConn for its existing SubConns.
|
// ClientConn.RemoveSubConn for its existing SubConns.
|
||||||
Close()
|
Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ConnectivityStateEvaluator takes the connectivity states of multiple SubConns
|
||||||
|
// and returns one aggregated connectivity state.
|
||||||
|
//
|
||||||
|
// It's not thread safe.
|
||||||
|
type ConnectivityStateEvaluator struct {
|
||||||
|
numReady uint64 // Number of addrConns in ready state.
|
||||||
|
numConnecting uint64 // Number of addrConns in connecting state.
|
||||||
|
numTransientFailure uint64 // Number of addrConns in transientFailure.
|
||||||
|
}
|
||||||
|
|
||||||
|
// RecordTransition records state change happening in subConn and based on that
|
||||||
|
// it evaluates what aggregated state should be.
|
||||||
|
//
|
||||||
|
// - If at least one SubConn in Ready, the aggregated state is Ready;
|
||||||
|
// - Else if at least one SubConn in Connecting, the aggregated state is Connecting;
|
||||||
|
// - Else the aggregated state is TransientFailure.
|
||||||
|
//
|
||||||
|
// Idle and Shutdown are not considered.
|
||||||
|
func (cse *ConnectivityStateEvaluator) RecordTransition(oldState, newState connectivity.State) connectivity.State {
|
||||||
|
// Update counters.
|
||||||
|
for idx, state := range []connectivity.State{oldState, newState} {
|
||||||
|
updateVal := 2*uint64(idx) - 1 // -1 for oldState and +1 for new.
|
||||||
|
switch state {
|
||||||
|
case connectivity.Ready:
|
||||||
|
cse.numReady += updateVal
|
||||||
|
case connectivity.Connecting:
|
||||||
|
cse.numConnecting += updateVal
|
||||||
|
case connectivity.TransientFailure:
|
||||||
|
cse.numTransientFailure += updateVal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate.
|
||||||
|
if cse.numReady > 0 {
|
||||||
|
return connectivity.Ready
|
||||||
|
}
|
||||||
|
if cse.numConnecting > 0 {
|
||||||
|
return connectivity.Connecting
|
||||||
|
}
|
||||||
|
return connectivity.TransientFailure
|
||||||
|
}
|
||||||
|
56
vendor/google.golang.org/grpc/balancer_v1_wrapper.go
generated
vendored
56
vendor/google.golang.org/grpc/balancer_v1_wrapper.go
generated
vendored
@ -55,7 +55,7 @@ func (bwb *balancerWrapperBuilder) Build(cc balancer.ClientConn, opts balancer.B
|
|||||||
startCh: make(chan struct{}),
|
startCh: make(chan struct{}),
|
||||||
conns: make(map[resolver.Address]balancer.SubConn),
|
conns: make(map[resolver.Address]balancer.SubConn),
|
||||||
connSt: make(map[balancer.SubConn]*scState),
|
connSt: make(map[balancer.SubConn]*scState),
|
||||||
csEvltr: &connectivityStateEvaluator{},
|
csEvltr: &balancer.ConnectivityStateEvaluator{},
|
||||||
state: connectivity.Idle,
|
state: connectivity.Idle,
|
||||||
}
|
}
|
||||||
cc.UpdateBalancerState(connectivity.Idle, bw)
|
cc.UpdateBalancerState(connectivity.Idle, bw)
|
||||||
@ -80,10 +80,6 @@ type balancerWrapper struct {
|
|||||||
cc balancer.ClientConn
|
cc balancer.ClientConn
|
||||||
targetAddr string // Target without the scheme.
|
targetAddr string // Target without the scheme.
|
||||||
|
|
||||||
// To aggregate the connectivity state.
|
|
||||||
csEvltr *connectivityStateEvaluator
|
|
||||||
state connectivity.State
|
|
||||||
|
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
conns map[resolver.Address]balancer.SubConn
|
conns map[resolver.Address]balancer.SubConn
|
||||||
connSt map[balancer.SubConn]*scState
|
connSt map[balancer.SubConn]*scState
|
||||||
@ -92,6 +88,10 @@ type balancerWrapper struct {
|
|||||||
// - NewSubConn is created, cc wants to notify balancer of state changes;
|
// - NewSubConn is created, cc wants to notify balancer of state changes;
|
||||||
// - Build hasn't return, cc doesn't have access to balancer.
|
// - Build hasn't return, cc doesn't have access to balancer.
|
||||||
startCh chan struct{}
|
startCh chan struct{}
|
||||||
|
|
||||||
|
// To aggregate the connectivity state.
|
||||||
|
csEvltr *balancer.ConnectivityStateEvaluator
|
||||||
|
state connectivity.State
|
||||||
}
|
}
|
||||||
|
|
||||||
// lbWatcher watches the Notify channel of the balancer and manages
|
// lbWatcher watches the Notify channel of the balancer and manages
|
||||||
@ -248,7 +248,7 @@ func (bw *balancerWrapper) HandleSubConnStateChange(sc balancer.SubConn, s conne
|
|||||||
scSt.down(errConnClosing)
|
scSt.down(errConnClosing)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sa := bw.csEvltr.recordTransition(oldS, s)
|
sa := bw.csEvltr.RecordTransition(oldS, s)
|
||||||
if bw.state != sa {
|
if bw.state != sa {
|
||||||
bw.state = sa
|
bw.state = sa
|
||||||
}
|
}
|
||||||
@ -326,47 +326,3 @@ func (bw *balancerWrapper) Pick(ctx context.Context, opts balancer.PickOptions)
|
|||||||
|
|
||||||
return sc, done, nil
|
return sc, done, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// connectivityStateEvaluator gets updated by addrConns when their
|
|
||||||
// states transition, based on which it evaluates the state of
|
|
||||||
// ClientConn.
|
|
||||||
type connectivityStateEvaluator struct {
|
|
||||||
mu sync.Mutex
|
|
||||||
numReady uint64 // Number of addrConns in ready state.
|
|
||||||
numConnecting uint64 // Number of addrConns in connecting state.
|
|
||||||
numTransientFailure uint64 // Number of addrConns in transientFailure.
|
|
||||||
}
|
|
||||||
|
|
||||||
// recordTransition records state change happening in every subConn and based on
|
|
||||||
// that it evaluates what aggregated state should be.
|
|
||||||
// It can only transition between Ready, Connecting and TransientFailure. Other states,
|
|
||||||
// Idle and Shutdown are transitioned into by ClientConn; in the beginning of the connection
|
|
||||||
// before any subConn is created ClientConn is in idle state. In the end when ClientConn
|
|
||||||
// closes it is in Shutdown state.
|
|
||||||
// TODO Note that in later releases, a ClientConn with no activity will be put into an Idle state.
|
|
||||||
func (cse *connectivityStateEvaluator) recordTransition(oldState, newState connectivity.State) connectivity.State {
|
|
||||||
cse.mu.Lock()
|
|
||||||
defer cse.mu.Unlock()
|
|
||||||
|
|
||||||
// Update counters.
|
|
||||||
for idx, state := range []connectivity.State{oldState, newState} {
|
|
||||||
updateVal := 2*uint64(idx) - 1 // -1 for oldState and +1 for new.
|
|
||||||
switch state {
|
|
||||||
case connectivity.Ready:
|
|
||||||
cse.numReady += updateVal
|
|
||||||
case connectivity.Connecting:
|
|
||||||
cse.numConnecting += updateVal
|
|
||||||
case connectivity.TransientFailure:
|
|
||||||
cse.numTransientFailure += updateVal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate.
|
|
||||||
if cse.numReady > 0 {
|
|
||||||
return connectivity.Ready
|
|
||||||
}
|
|
||||||
if cse.numConnecting > 0 {
|
|
||||||
return connectivity.Connecting
|
|
||||||
}
|
|
||||||
return connectivity.TransientFailure
|
|
||||||
}
|
|
||||||
|
49
vendor/google.golang.org/grpc/clientconn.go
generated
vendored
49
vendor/google.golang.org/grpc/clientconn.go
generated
vendored
@ -32,11 +32,13 @@ import (
|
|||||||
"golang.org/x/net/trace"
|
"golang.org/x/net/trace"
|
||||||
"google.golang.org/grpc/balancer"
|
"google.golang.org/grpc/balancer"
|
||||||
_ "google.golang.org/grpc/balancer/roundrobin" // To register roundrobin.
|
_ "google.golang.org/grpc/balancer/roundrobin" // To register roundrobin.
|
||||||
"google.golang.org/grpc/channelz"
|
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/connectivity"
|
"google.golang.org/grpc/connectivity"
|
||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
"google.golang.org/grpc/grpclog"
|
"google.golang.org/grpc/grpclog"
|
||||||
|
"google.golang.org/grpc/internal"
|
||||||
|
"google.golang.org/grpc/internal/backoff"
|
||||||
|
"google.golang.org/grpc/internal/channelz"
|
||||||
"google.golang.org/grpc/keepalive"
|
"google.golang.org/grpc/keepalive"
|
||||||
"google.golang.org/grpc/resolver"
|
"google.golang.org/grpc/resolver"
|
||||||
_ "google.golang.org/grpc/resolver/dns" // To register dns resolver.
|
_ "google.golang.org/grpc/resolver/dns" // To register dns resolver.
|
||||||
@ -49,6 +51,8 @@ import (
|
|||||||
const (
|
const (
|
||||||
// minimum time to give a connection to complete
|
// minimum time to give a connection to complete
|
||||||
minConnectTimeout = 20 * time.Second
|
minConnectTimeout = 20 * time.Second
|
||||||
|
// must match grpclbName in grpclb/grpclb.go
|
||||||
|
grpclbName = "grpclb"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -97,7 +101,7 @@ type dialOptions struct {
|
|||||||
streamInt StreamClientInterceptor
|
streamInt StreamClientInterceptor
|
||||||
cp Compressor
|
cp Compressor
|
||||||
dc Decompressor
|
dc Decompressor
|
||||||
bs backoffStrategy
|
bs backoff.Strategy
|
||||||
block bool
|
block bool
|
||||||
insecure bool
|
insecure bool
|
||||||
timeout time.Duration
|
timeout time.Duration
|
||||||
@ -275,17 +279,17 @@ func WithBackoffMaxDelay(md time.Duration) DialOption {
|
|||||||
// Use WithBackoffMaxDelay until more parameters on BackoffConfig are opened up
|
// Use WithBackoffMaxDelay until more parameters on BackoffConfig are opened up
|
||||||
// for use.
|
// for use.
|
||||||
func WithBackoffConfig(b BackoffConfig) DialOption {
|
func WithBackoffConfig(b BackoffConfig) DialOption {
|
||||||
// Set defaults to ensure that provided BackoffConfig is valid and
|
|
||||||
// unexported fields get default values.
|
return withBackoff(backoff.Exponential{
|
||||||
setDefaults(&b)
|
MaxDelay: b.MaxDelay,
|
||||||
return withBackoff(b)
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// withBackoff sets the backoff strategy used for connectRetryNum after a
|
// withBackoff sets the backoff strategy used for connectRetryNum after a
|
||||||
// failed connection attempt.
|
// failed connection attempt.
|
||||||
//
|
//
|
||||||
// This can be exported if arbitrary backoff strategies are allowed by gRPC.
|
// This can be exported if arbitrary backoff strategies are allowed by gRPC.
|
||||||
func withBackoff(bs backoffStrategy) DialOption {
|
func withBackoff(bs backoff.Strategy) DialOption {
|
||||||
return func(o *dialOptions) {
|
return func(o *dialOptions) {
|
||||||
o.bs = bs
|
o.bs = bs
|
||||||
}
|
}
|
||||||
@ -340,6 +344,11 @@ func withContextDialer(f func(context.Context, string) (net.Conn, error)) DialOp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
internal.WithContextDialer = withContextDialer
|
||||||
|
internal.WithResolverBuilder = withResolverBuilder
|
||||||
|
}
|
||||||
|
|
||||||
// WithDialer returns a DialOption that specifies a function to use for dialing network addresses.
|
// WithDialer returns a DialOption that specifies a function to use for dialing network addresses.
|
||||||
// If FailOnNonTempDialError() is set to true, and an error is returned by f, gRPC checks the error's
|
// If FailOnNonTempDialError() is set to true, and an error is returned by f, gRPC checks the error's
|
||||||
// Temporary() method to decide if it should try to reconnect to the network address.
|
// Temporary() method to decide if it should try to reconnect to the network address.
|
||||||
@ -469,19 +478,9 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !cc.dopts.insecure {
|
err = cc.validateClientOptions()
|
||||||
if cc.dopts.copts.TransportCredentials == nil {
|
if err != nil {
|
||||||
return nil, errNoTransportSecurity
|
return nil, err
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if cc.dopts.copts.TransportCredentials != nil {
|
|
||||||
return nil, errCredentialsConflict
|
|
||||||
}
|
|
||||||
for _, cd := range cc.dopts.copts.PerRPCCredentials {
|
|
||||||
if cd.RequireTransportSecurity() {
|
|
||||||
return nil, errTransportCredentialsMissing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cc.mkp = cc.dopts.copts.KeepaliveParams
|
cc.mkp = cc.dopts.copts.KeepaliveParams
|
||||||
@ -532,7 +531,9 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if cc.dopts.bs == nil {
|
if cc.dopts.bs == nil {
|
||||||
cc.dopts.bs = DefaultBackoffConfig
|
cc.dopts.bs = backoff.Exponential{
|
||||||
|
MaxDelay: DefaultBackoffConfig.MaxDelay,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if cc.dopts.resolverBuilder == nil {
|
if cc.dopts.resolverBuilder == nil {
|
||||||
// Only try to parse target when resolver builder is not already set.
|
// Only try to parse target when resolver builder is not already set.
|
||||||
@ -1052,9 +1053,9 @@ func (cc *ClientConn) handleServiceConfig(js string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cc *ClientConn) resolveNow(o resolver.ResolveNowOption) {
|
func (cc *ClientConn) resolveNow(o resolver.ResolveNowOption) {
|
||||||
cc.mu.Lock()
|
cc.mu.RLock()
|
||||||
r := cc.resolverWrapper
|
r := cc.resolverWrapper
|
||||||
cc.mu.Unlock()
|
cc.mu.RUnlock()
|
||||||
if r == nil {
|
if r == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1203,7 +1204,7 @@ func (ac *addrConn) resetTransport() error {
|
|||||||
// This means either a successful HTTP2 connection was established
|
// This means either a successful HTTP2 connection was established
|
||||||
// or this is the first time this addrConn is trying to establish a
|
// or this is the first time this addrConn is trying to establish a
|
||||||
// connection.
|
// connection.
|
||||||
backoffFor := ac.dopts.bs.backoff(connectRetryNum) // time.Duration.
|
backoffFor := ac.dopts.bs.Backoff(connectRetryNum) // time.Duration.
|
||||||
// This will be the duration that dial gets to finish.
|
// This will be the duration that dial gets to finish.
|
||||||
dialDuration := getMinConnectTimeout()
|
dialDuration := getMinConnectTimeout()
|
||||||
if backoffFor > dialDuration {
|
if backoffFor > dialDuration {
|
||||||
|
13
vendor/google.golang.org/grpc/codes/codes.go
generated
vendored
13
vendor/google.golang.org/grpc/codes/codes.go
generated
vendored
@ -22,6 +22,7 @@ package codes // import "google.golang.org/grpc/codes"
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A Code is an unsigned 32-bit error code as defined in the gRPC spec.
|
// A Code is an unsigned 32-bit error code as defined in the gRPC spec.
|
||||||
@ -143,6 +144,8 @@ const (
|
|||||||
// Unauthenticated indicates the request does not have valid
|
// Unauthenticated indicates the request does not have valid
|
||||||
// authentication credentials for the operation.
|
// authentication credentials for the operation.
|
||||||
Unauthenticated Code = 16
|
Unauthenticated Code = 16
|
||||||
|
|
||||||
|
_maxCode = 17
|
||||||
)
|
)
|
||||||
|
|
||||||
var strToCode = map[string]Code{
|
var strToCode = map[string]Code{
|
||||||
@ -176,6 +179,16 @@ func (c *Code) UnmarshalJSON(b []byte) error {
|
|||||||
if c == nil {
|
if c == nil {
|
||||||
return fmt.Errorf("nil receiver passed to UnmarshalJSON")
|
return fmt.Errorf("nil receiver passed to UnmarshalJSON")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ci, err := strconv.ParseUint(string(b), 10, 32); err == nil {
|
||||||
|
if ci >= _maxCode {
|
||||||
|
return fmt.Errorf("invalid code: %q", ci)
|
||||||
|
}
|
||||||
|
|
||||||
|
*c = Code(ci)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
if jc, ok := strToCode[string(b)]; ok {
|
if jc, ok := strToCode[string(b)]; ok {
|
||||||
*c = jc
|
*c = jc
|
||||||
return nil
|
return nil
|
||||||
|
39
vendor/google.golang.org/grpc/dial.go
generated
vendored
Normal file
39
vendor/google.golang.org/grpc/dial.go
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// +build !js !wasm
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2018 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package grpc
|
||||||
|
|
||||||
|
func (cc ClientConn) validateClientOptions() error {
|
||||||
|
if !cc.dopts.insecure {
|
||||||
|
if cc.dopts.copts.TransportCredentials == nil {
|
||||||
|
return errNoTransportSecurity
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if cc.dopts.copts.TransportCredentials != nil {
|
||||||
|
return errCredentialsConflict
|
||||||
|
}
|
||||||
|
for _, cd := range cc.dopts.copts.PerRPCCredentials {
|
||||||
|
if cd.RequireTransportSecurity() {
|
||||||
|
return errTransportCredentialsMissing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
39
vendor/google.golang.org/grpc/dial_js.go
generated
vendored
Normal file
39
vendor/google.golang.org/grpc/dial_js.go
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// +build js,wasm
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2018 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package grpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// errTransportSecurity indicates the client was attempting an RPC call
|
||||||
|
// from a WASM client with TransportCredentials configured.
|
||||||
|
errTransportSecurity = errors.New("cannot configure transport security for WASM clients")
|
||||||
|
)
|
||||||
|
|
||||||
|
func (cc ClientConn) validateClientOptions() error {
|
||||||
|
if cc.dopts.copts.TransportCredentials != nil {
|
||||||
|
return errTransportSecurity
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
341
vendor/google.golang.org/grpc/grpclb.go
generated
vendored
341
vendor/google.golang.org/grpc/grpclb.go
generated
vendored
@ -1,341 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* Copyright 2016 gRPC authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
package grpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
"google.golang.org/grpc/balancer"
|
|
||||||
"google.golang.org/grpc/connectivity"
|
|
||||||
lbpb "google.golang.org/grpc/grpclb/grpc_lb_v1/messages"
|
|
||||||
"google.golang.org/grpc/grpclog"
|
|
||||||
"google.golang.org/grpc/resolver"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
lbTokeyKey = "lb-token"
|
|
||||||
defaultFallbackTimeout = 10 * time.Second
|
|
||||||
grpclbName = "grpclb"
|
|
||||||
)
|
|
||||||
|
|
||||||
func convertDuration(d *lbpb.Duration) time.Duration {
|
|
||||||
if d == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return time.Duration(d.Seconds)*time.Second + time.Duration(d.Nanos)*time.Nanosecond
|
|
||||||
}
|
|
||||||
|
|
||||||
// Client API for LoadBalancer service.
|
|
||||||
// Mostly copied from generated pb.go file.
|
|
||||||
// To avoid circular dependency.
|
|
||||||
type loadBalancerClient struct {
|
|
||||||
cc *ClientConn
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *loadBalancerClient) BalanceLoad(ctx context.Context, opts ...CallOption) (*balanceLoadClientStream, error) {
|
|
||||||
desc := &StreamDesc{
|
|
||||||
StreamName: "BalanceLoad",
|
|
||||||
ServerStreams: true,
|
|
||||||
ClientStreams: true,
|
|
||||||
}
|
|
||||||
stream, err := c.cc.NewStream(ctx, desc, "/grpc.lb.v1.LoadBalancer/BalanceLoad", opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
x := &balanceLoadClientStream{stream}
|
|
||||||
return x, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type balanceLoadClientStream struct {
|
|
||||||
ClientStream
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *balanceLoadClientStream) Send(m *lbpb.LoadBalanceRequest) error {
|
|
||||||
return x.ClientStream.SendMsg(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *balanceLoadClientStream) Recv() (*lbpb.LoadBalanceResponse, error) {
|
|
||||||
m := new(lbpb.LoadBalanceResponse)
|
|
||||||
if err := x.ClientStream.RecvMsg(m); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return m, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
balancer.Register(newLBBuilder())
|
|
||||||
}
|
|
||||||
|
|
||||||
// newLBBuilder creates a builder for grpclb.
|
|
||||||
func newLBBuilder() balancer.Builder {
|
|
||||||
return NewLBBuilderWithFallbackTimeout(defaultFallbackTimeout)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewLBBuilderWithFallbackTimeout creates a grpclb builder with the given
|
|
||||||
// fallbackTimeout. If no response is received from the remote balancer within
|
|
||||||
// fallbackTimeout, the backend addresses from the resolved address list will be
|
|
||||||
// used.
|
|
||||||
//
|
|
||||||
// Only call this function when a non-default fallback timeout is needed.
|
|
||||||
func NewLBBuilderWithFallbackTimeout(fallbackTimeout time.Duration) balancer.Builder {
|
|
||||||
return &lbBuilder{
|
|
||||||
fallbackTimeout: fallbackTimeout,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type lbBuilder struct {
|
|
||||||
fallbackTimeout time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *lbBuilder) Name() string {
|
|
||||||
return grpclbName
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *lbBuilder) Build(cc balancer.ClientConn, opt balancer.BuildOptions) balancer.Balancer {
|
|
||||||
// This generates a manual resolver builder with a random scheme. This
|
|
||||||
// scheme will be used to dial to remote LB, so we can send filtered address
|
|
||||||
// updates to remote LB ClientConn using this manual resolver.
|
|
||||||
scheme := "grpclb_internal_" + strconv.FormatInt(time.Now().UnixNano(), 36)
|
|
||||||
r := &lbManualResolver{scheme: scheme, ccb: cc}
|
|
||||||
|
|
||||||
var target string
|
|
||||||
targetSplitted := strings.Split(cc.Target(), ":///")
|
|
||||||
if len(targetSplitted) < 2 {
|
|
||||||
target = cc.Target()
|
|
||||||
} else {
|
|
||||||
target = targetSplitted[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
lb := &lbBalancer{
|
|
||||||
cc: newLBCacheClientConn(cc),
|
|
||||||
target: target,
|
|
||||||
opt: opt,
|
|
||||||
fallbackTimeout: b.fallbackTimeout,
|
|
||||||
doneCh: make(chan struct{}),
|
|
||||||
|
|
||||||
manualResolver: r,
|
|
||||||
csEvltr: &connectivityStateEvaluator{},
|
|
||||||
subConns: make(map[resolver.Address]balancer.SubConn),
|
|
||||||
scStates: make(map[balancer.SubConn]connectivity.State),
|
|
||||||
picker: &errPicker{err: balancer.ErrNoSubConnAvailable},
|
|
||||||
clientStats: &rpcStats{},
|
|
||||||
}
|
|
||||||
|
|
||||||
return lb
|
|
||||||
}
|
|
||||||
|
|
||||||
type lbBalancer struct {
|
|
||||||
cc *lbCacheClientConn
|
|
||||||
target string
|
|
||||||
opt balancer.BuildOptions
|
|
||||||
fallbackTimeout time.Duration
|
|
||||||
doneCh chan struct{}
|
|
||||||
|
|
||||||
// manualResolver is used in the remote LB ClientConn inside grpclb. When
|
|
||||||
// resolved address updates are received by grpclb, filtered updates will be
|
|
||||||
// send to remote LB ClientConn through this resolver.
|
|
||||||
manualResolver *lbManualResolver
|
|
||||||
// The ClientConn to talk to the remote balancer.
|
|
||||||
ccRemoteLB *ClientConn
|
|
||||||
|
|
||||||
// Support client side load reporting. Each picker gets a reference to this,
|
|
||||||
// and will update its content.
|
|
||||||
clientStats *rpcStats
|
|
||||||
|
|
||||||
mu sync.Mutex // guards everything following.
|
|
||||||
// The full server list including drops, used to check if the newly received
|
|
||||||
// serverList contains anything new. Each generate picker will also have
|
|
||||||
// reference to this list to do the first layer pick.
|
|
||||||
fullServerList []*lbpb.Server
|
|
||||||
// All backends addresses, with metadata set to nil. This list contains all
|
|
||||||
// backend addresses in the same order and with the same duplicates as in
|
|
||||||
// serverlist. When generating picker, a SubConn slice with the same order
|
|
||||||
// but with only READY SCs will be gerenated.
|
|
||||||
backendAddrs []resolver.Address
|
|
||||||
// Roundrobin functionalities.
|
|
||||||
csEvltr *connectivityStateEvaluator
|
|
||||||
state connectivity.State
|
|
||||||
subConns map[resolver.Address]balancer.SubConn // Used to new/remove SubConn.
|
|
||||||
scStates map[balancer.SubConn]connectivity.State // Used to filter READY SubConns.
|
|
||||||
picker balancer.Picker
|
|
||||||
// Support fallback to resolved backend addresses if there's no response
|
|
||||||
// from remote balancer within fallbackTimeout.
|
|
||||||
fallbackTimerExpired bool
|
|
||||||
serverListReceived bool
|
|
||||||
// resolvedBackendAddrs is resolvedAddrs minus remote balancers. It's set
|
|
||||||
// when resolved address updates are received, and read in the goroutine
|
|
||||||
// handling fallback.
|
|
||||||
resolvedBackendAddrs []resolver.Address
|
|
||||||
}
|
|
||||||
|
|
||||||
// regeneratePicker takes a snapshot of the balancer, and generates a picker from
|
|
||||||
// it. The picker
|
|
||||||
// - always returns ErrTransientFailure if the balancer is in TransientFailure,
|
|
||||||
// - does two layer roundrobin pick otherwise.
|
|
||||||
// Caller must hold lb.mu.
|
|
||||||
func (lb *lbBalancer) regeneratePicker() {
|
|
||||||
if lb.state == connectivity.TransientFailure {
|
|
||||||
lb.picker = &errPicker{err: balancer.ErrTransientFailure}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var readySCs []balancer.SubConn
|
|
||||||
for _, a := range lb.backendAddrs {
|
|
||||||
if sc, ok := lb.subConns[a]; ok {
|
|
||||||
if st, ok := lb.scStates[sc]; ok && st == connectivity.Ready {
|
|
||||||
readySCs = append(readySCs, sc)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(lb.fullServerList) <= 0 {
|
|
||||||
if len(readySCs) <= 0 {
|
|
||||||
lb.picker = &errPicker{err: balancer.ErrNoSubConnAvailable}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
lb.picker = &rrPicker{subConns: readySCs}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
lb.picker = &lbPicker{
|
|
||||||
serverList: lb.fullServerList,
|
|
||||||
subConns: readySCs,
|
|
||||||
stats: lb.clientStats,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (lb *lbBalancer) HandleSubConnStateChange(sc balancer.SubConn, s connectivity.State) {
|
|
||||||
grpclog.Infof("lbBalancer: handle SubConn state change: %p, %v", sc, s)
|
|
||||||
lb.mu.Lock()
|
|
||||||
defer lb.mu.Unlock()
|
|
||||||
|
|
||||||
oldS, ok := lb.scStates[sc]
|
|
||||||
if !ok {
|
|
||||||
grpclog.Infof("lbBalancer: got state changes for an unknown SubConn: %p, %v", sc, s)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
lb.scStates[sc] = s
|
|
||||||
switch s {
|
|
||||||
case connectivity.Idle:
|
|
||||||
sc.Connect()
|
|
||||||
case connectivity.Shutdown:
|
|
||||||
// When an address was removed by resolver, b called RemoveSubConn but
|
|
||||||
// kept the sc's state in scStates. Remove state for this sc here.
|
|
||||||
delete(lb.scStates, sc)
|
|
||||||
}
|
|
||||||
|
|
||||||
oldAggrState := lb.state
|
|
||||||
lb.state = lb.csEvltr.recordTransition(oldS, s)
|
|
||||||
|
|
||||||
// Regenerate picker when one of the following happens:
|
|
||||||
// - this sc became ready from not-ready
|
|
||||||
// - this sc became not-ready from ready
|
|
||||||
// - the aggregated state of balancer became TransientFailure from non-TransientFailure
|
|
||||||
// - the aggregated state of balancer became non-TransientFailure from TransientFailure
|
|
||||||
if (oldS == connectivity.Ready) != (s == connectivity.Ready) ||
|
|
||||||
(lb.state == connectivity.TransientFailure) != (oldAggrState == connectivity.TransientFailure) {
|
|
||||||
lb.regeneratePicker()
|
|
||||||
}
|
|
||||||
|
|
||||||
lb.cc.UpdateBalancerState(lb.state, lb.picker)
|
|
||||||
}
|
|
||||||
|
|
||||||
// fallbackToBackendsAfter blocks for fallbackTimeout and falls back to use
|
|
||||||
// resolved backends (backends received from resolver, not from remote balancer)
|
|
||||||
// if no connection to remote balancers was successful.
|
|
||||||
func (lb *lbBalancer) fallbackToBackendsAfter(fallbackTimeout time.Duration) {
|
|
||||||
timer := time.NewTimer(fallbackTimeout)
|
|
||||||
defer timer.Stop()
|
|
||||||
select {
|
|
||||||
case <-timer.C:
|
|
||||||
case <-lb.doneCh:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
lb.mu.Lock()
|
|
||||||
if lb.serverListReceived {
|
|
||||||
lb.mu.Unlock()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
lb.fallbackTimerExpired = true
|
|
||||||
lb.refreshSubConns(lb.resolvedBackendAddrs)
|
|
||||||
lb.mu.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
// HandleResolvedAddrs sends the updated remoteLB addresses to remoteLB
|
|
||||||
// clientConn. The remoteLB clientConn will handle creating/removing remoteLB
|
|
||||||
// connections.
|
|
||||||
func (lb *lbBalancer) HandleResolvedAddrs(addrs []resolver.Address, err error) {
|
|
||||||
grpclog.Infof("lbBalancer: handleResolvedResult: %+v", addrs)
|
|
||||||
if len(addrs) <= 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var remoteBalancerAddrs, backendAddrs []resolver.Address
|
|
||||||
for _, a := range addrs {
|
|
||||||
if a.Type == resolver.GRPCLB {
|
|
||||||
remoteBalancerAddrs = append(remoteBalancerAddrs, a)
|
|
||||||
} else {
|
|
||||||
backendAddrs = append(backendAddrs, a)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if lb.ccRemoteLB == nil {
|
|
||||||
if len(remoteBalancerAddrs) <= 0 {
|
|
||||||
grpclog.Errorf("grpclb: no remote balancer address is available, should never happen")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// First time receiving resolved addresses, create a cc to remote
|
|
||||||
// balancers.
|
|
||||||
lb.dialRemoteLB(remoteBalancerAddrs[0].ServerName)
|
|
||||||
// Start the fallback goroutine.
|
|
||||||
go lb.fallbackToBackendsAfter(lb.fallbackTimeout)
|
|
||||||
}
|
|
||||||
|
|
||||||
// cc to remote balancers uses lb.manualResolver. Send the updated remote
|
|
||||||
// balancer addresses to it through manualResolver.
|
|
||||||
lb.manualResolver.NewAddress(remoteBalancerAddrs)
|
|
||||||
|
|
||||||
lb.mu.Lock()
|
|
||||||
lb.resolvedBackendAddrs = backendAddrs
|
|
||||||
// If serverListReceived is true, connection to remote balancer was
|
|
||||||
// successful and there's no need to do fallback anymore.
|
|
||||||
// If fallbackTimerExpired is false, fallback hasn't happened yet.
|
|
||||||
if !lb.serverListReceived && lb.fallbackTimerExpired {
|
|
||||||
// This means we received a new list of resolved backends, and we are
|
|
||||||
// still in fallback mode. Need to update the list of backends we are
|
|
||||||
// using to the new list of backends.
|
|
||||||
lb.refreshSubConns(lb.resolvedBackendAddrs)
|
|
||||||
}
|
|
||||||
lb.mu.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (lb *lbBalancer) Close() {
|
|
||||||
select {
|
|
||||||
case <-lb.doneCh:
|
|
||||||
return
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
close(lb.doneCh)
|
|
||||||
if lb.ccRemoteLB != nil {
|
|
||||||
lb.ccRemoteLB.Close()
|
|
||||||
}
|
|
||||||
lb.cc.close()
|
|
||||||
}
|
|
799
vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/messages/messages.pb.go
generated
vendored
799
vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/messages/messages.pb.go
generated
vendored
@ -1,799 +0,0 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
|
||||||
// source: grpc_lb_v1/messages/messages.proto
|
|
||||||
|
|
||||||
package messages // import "google.golang.org/grpc/grpclb/grpc_lb_v1/messages"
|
|
||||||
|
|
||||||
import proto "github.com/golang/protobuf/proto"
|
|
||||||
import fmt "fmt"
|
|
||||||
import math "math"
|
|
||||||
|
|
||||||
// Reference imports to suppress errors if they are not otherwise used.
|
|
||||||
var _ = proto.Marshal
|
|
||||||
var _ = fmt.Errorf
|
|
||||||
var _ = math.Inf
|
|
||||||
|
|
||||||
// This is a compile-time assertion to ensure that this generated file
|
|
||||||
// is compatible with the proto package it is being compiled against.
|
|
||||||
// A compilation error at this line likely means your copy of the
|
|
||||||
// proto package needs to be updated.
|
|
||||||
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
|
||||||
|
|
||||||
type Duration struct {
|
|
||||||
// Signed seconds of the span of time. Must be from -315,576,000,000
|
|
||||||
// to +315,576,000,000 inclusive.
|
|
||||||
Seconds int64 `protobuf:"varint,1,opt,name=seconds" json:"seconds,omitempty"`
|
|
||||||
// Signed fractions of a second at nanosecond resolution of the span
|
|
||||||
// of time. Durations less than one second are represented with a 0
|
|
||||||
// `seconds` field and a positive or negative `nanos` field. For durations
|
|
||||||
// of one second or more, a non-zero value for the `nanos` field must be
|
|
||||||
// of the same sign as the `seconds` field. Must be from -999,999,999
|
|
||||||
// to +999,999,999 inclusive.
|
|
||||||
Nanos int32 `protobuf:"varint,2,opt,name=nanos" json:"nanos,omitempty"`
|
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
|
||||||
XXX_unrecognized []byte `json:"-"`
|
|
||||||
XXX_sizecache int32 `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Duration) Reset() { *m = Duration{} }
|
|
||||||
func (m *Duration) String() string { return proto.CompactTextString(m) }
|
|
||||||
func (*Duration) ProtoMessage() {}
|
|
||||||
func (*Duration) Descriptor() ([]byte, []int) {
|
|
||||||
return fileDescriptor_messages_b81c731f0e83edbd, []int{0}
|
|
||||||
}
|
|
||||||
func (m *Duration) XXX_Unmarshal(b []byte) error {
|
|
||||||
return xxx_messageInfo_Duration.Unmarshal(m, b)
|
|
||||||
}
|
|
||||||
func (m *Duration) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
|
||||||
return xxx_messageInfo_Duration.Marshal(b, m, deterministic)
|
|
||||||
}
|
|
||||||
func (dst *Duration) XXX_Merge(src proto.Message) {
|
|
||||||
xxx_messageInfo_Duration.Merge(dst, src)
|
|
||||||
}
|
|
||||||
func (m *Duration) XXX_Size() int {
|
|
||||||
return xxx_messageInfo_Duration.Size(m)
|
|
||||||
}
|
|
||||||
func (m *Duration) XXX_DiscardUnknown() {
|
|
||||||
xxx_messageInfo_Duration.DiscardUnknown(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
var xxx_messageInfo_Duration proto.InternalMessageInfo
|
|
||||||
|
|
||||||
func (m *Duration) GetSeconds() int64 {
|
|
||||||
if m != nil {
|
|
||||||
return m.Seconds
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Duration) GetNanos() int32 {
|
|
||||||
if m != nil {
|
|
||||||
return m.Nanos
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type Timestamp struct {
|
|
||||||
// Represents seconds of UTC time since Unix epoch
|
|
||||||
// 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
|
|
||||||
// 9999-12-31T23:59:59Z inclusive.
|
|
||||||
Seconds int64 `protobuf:"varint,1,opt,name=seconds" json:"seconds,omitempty"`
|
|
||||||
// Non-negative fractions of a second at nanosecond resolution. Negative
|
|
||||||
// second values with fractions must still have non-negative nanos values
|
|
||||||
// that count forward in time. Must be from 0 to 999,999,999
|
|
||||||
// inclusive.
|
|
||||||
Nanos int32 `protobuf:"varint,2,opt,name=nanos" json:"nanos,omitempty"`
|
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
|
||||||
XXX_unrecognized []byte `json:"-"`
|
|
||||||
XXX_sizecache int32 `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Timestamp) Reset() { *m = Timestamp{} }
|
|
||||||
func (m *Timestamp) String() string { return proto.CompactTextString(m) }
|
|
||||||
func (*Timestamp) ProtoMessage() {}
|
|
||||||
func (*Timestamp) Descriptor() ([]byte, []int) {
|
|
||||||
return fileDescriptor_messages_b81c731f0e83edbd, []int{1}
|
|
||||||
}
|
|
||||||
func (m *Timestamp) XXX_Unmarshal(b []byte) error {
|
|
||||||
return xxx_messageInfo_Timestamp.Unmarshal(m, b)
|
|
||||||
}
|
|
||||||
func (m *Timestamp) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
|
||||||
return xxx_messageInfo_Timestamp.Marshal(b, m, deterministic)
|
|
||||||
}
|
|
||||||
func (dst *Timestamp) XXX_Merge(src proto.Message) {
|
|
||||||
xxx_messageInfo_Timestamp.Merge(dst, src)
|
|
||||||
}
|
|
||||||
func (m *Timestamp) XXX_Size() int {
|
|
||||||
return xxx_messageInfo_Timestamp.Size(m)
|
|
||||||
}
|
|
||||||
func (m *Timestamp) XXX_DiscardUnknown() {
|
|
||||||
xxx_messageInfo_Timestamp.DiscardUnknown(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
var xxx_messageInfo_Timestamp proto.InternalMessageInfo
|
|
||||||
|
|
||||||
func (m *Timestamp) GetSeconds() int64 {
|
|
||||||
if m != nil {
|
|
||||||
return m.Seconds
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Timestamp) GetNanos() int32 {
|
|
||||||
if m != nil {
|
|
||||||
return m.Nanos
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type LoadBalanceRequest struct {
|
|
||||||
// Types that are valid to be assigned to LoadBalanceRequestType:
|
|
||||||
// *LoadBalanceRequest_InitialRequest
|
|
||||||
// *LoadBalanceRequest_ClientStats
|
|
||||||
LoadBalanceRequestType isLoadBalanceRequest_LoadBalanceRequestType `protobuf_oneof:"load_balance_request_type"`
|
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
|
||||||
XXX_unrecognized []byte `json:"-"`
|
|
||||||
XXX_sizecache int32 `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *LoadBalanceRequest) Reset() { *m = LoadBalanceRequest{} }
|
|
||||||
func (m *LoadBalanceRequest) String() string { return proto.CompactTextString(m) }
|
|
||||||
func (*LoadBalanceRequest) ProtoMessage() {}
|
|
||||||
func (*LoadBalanceRequest) Descriptor() ([]byte, []int) {
|
|
||||||
return fileDescriptor_messages_b81c731f0e83edbd, []int{2}
|
|
||||||
}
|
|
||||||
func (m *LoadBalanceRequest) XXX_Unmarshal(b []byte) error {
|
|
||||||
return xxx_messageInfo_LoadBalanceRequest.Unmarshal(m, b)
|
|
||||||
}
|
|
||||||
func (m *LoadBalanceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
|
||||||
return xxx_messageInfo_LoadBalanceRequest.Marshal(b, m, deterministic)
|
|
||||||
}
|
|
||||||
func (dst *LoadBalanceRequest) XXX_Merge(src proto.Message) {
|
|
||||||
xxx_messageInfo_LoadBalanceRequest.Merge(dst, src)
|
|
||||||
}
|
|
||||||
func (m *LoadBalanceRequest) XXX_Size() int {
|
|
||||||
return xxx_messageInfo_LoadBalanceRequest.Size(m)
|
|
||||||
}
|
|
||||||
func (m *LoadBalanceRequest) XXX_DiscardUnknown() {
|
|
||||||
xxx_messageInfo_LoadBalanceRequest.DiscardUnknown(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
var xxx_messageInfo_LoadBalanceRequest proto.InternalMessageInfo
|
|
||||||
|
|
||||||
type isLoadBalanceRequest_LoadBalanceRequestType interface {
|
|
||||||
isLoadBalanceRequest_LoadBalanceRequestType()
|
|
||||||
}
|
|
||||||
|
|
||||||
type LoadBalanceRequest_InitialRequest struct {
|
|
||||||
InitialRequest *InitialLoadBalanceRequest `protobuf:"bytes,1,opt,name=initial_request,json=initialRequest,oneof"`
|
|
||||||
}
|
|
||||||
type LoadBalanceRequest_ClientStats struct {
|
|
||||||
ClientStats *ClientStats `protobuf:"bytes,2,opt,name=client_stats,json=clientStats,oneof"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*LoadBalanceRequest_InitialRequest) isLoadBalanceRequest_LoadBalanceRequestType() {}
|
|
||||||
func (*LoadBalanceRequest_ClientStats) isLoadBalanceRequest_LoadBalanceRequestType() {}
|
|
||||||
|
|
||||||
func (m *LoadBalanceRequest) GetLoadBalanceRequestType() isLoadBalanceRequest_LoadBalanceRequestType {
|
|
||||||
if m != nil {
|
|
||||||
return m.LoadBalanceRequestType
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *LoadBalanceRequest) GetInitialRequest() *InitialLoadBalanceRequest {
|
|
||||||
if x, ok := m.GetLoadBalanceRequestType().(*LoadBalanceRequest_InitialRequest); ok {
|
|
||||||
return x.InitialRequest
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *LoadBalanceRequest) GetClientStats() *ClientStats {
|
|
||||||
if x, ok := m.GetLoadBalanceRequestType().(*LoadBalanceRequest_ClientStats); ok {
|
|
||||||
return x.ClientStats
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX_OneofFuncs is for the internal use of the proto package.
|
|
||||||
func (*LoadBalanceRequest) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
|
|
||||||
return _LoadBalanceRequest_OneofMarshaler, _LoadBalanceRequest_OneofUnmarshaler, _LoadBalanceRequest_OneofSizer, []interface{}{
|
|
||||||
(*LoadBalanceRequest_InitialRequest)(nil),
|
|
||||||
(*LoadBalanceRequest_ClientStats)(nil),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func _LoadBalanceRequest_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
|
|
||||||
m := msg.(*LoadBalanceRequest)
|
|
||||||
// load_balance_request_type
|
|
||||||
switch x := m.LoadBalanceRequestType.(type) {
|
|
||||||
case *LoadBalanceRequest_InitialRequest:
|
|
||||||
b.EncodeVarint(1<<3 | proto.WireBytes)
|
|
||||||
if err := b.EncodeMessage(x.InitialRequest); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
case *LoadBalanceRequest_ClientStats:
|
|
||||||
b.EncodeVarint(2<<3 | proto.WireBytes)
|
|
||||||
if err := b.EncodeMessage(x.ClientStats); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
case nil:
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("LoadBalanceRequest.LoadBalanceRequestType has unexpected type %T", x)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func _LoadBalanceRequest_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
|
|
||||||
m := msg.(*LoadBalanceRequest)
|
|
||||||
switch tag {
|
|
||||||
case 1: // load_balance_request_type.initial_request
|
|
||||||
if wire != proto.WireBytes {
|
|
||||||
return true, proto.ErrInternalBadWireType
|
|
||||||
}
|
|
||||||
msg := new(InitialLoadBalanceRequest)
|
|
||||||
err := b.DecodeMessage(msg)
|
|
||||||
m.LoadBalanceRequestType = &LoadBalanceRequest_InitialRequest{msg}
|
|
||||||
return true, err
|
|
||||||
case 2: // load_balance_request_type.client_stats
|
|
||||||
if wire != proto.WireBytes {
|
|
||||||
return true, proto.ErrInternalBadWireType
|
|
||||||
}
|
|
||||||
msg := new(ClientStats)
|
|
||||||
err := b.DecodeMessage(msg)
|
|
||||||
m.LoadBalanceRequestType = &LoadBalanceRequest_ClientStats{msg}
|
|
||||||
return true, err
|
|
||||||
default:
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func _LoadBalanceRequest_OneofSizer(msg proto.Message) (n int) {
|
|
||||||
m := msg.(*LoadBalanceRequest)
|
|
||||||
// load_balance_request_type
|
|
||||||
switch x := m.LoadBalanceRequestType.(type) {
|
|
||||||
case *LoadBalanceRequest_InitialRequest:
|
|
||||||
s := proto.Size(x.InitialRequest)
|
|
||||||
n += 1 // tag and wire
|
|
||||||
n += proto.SizeVarint(uint64(s))
|
|
||||||
n += s
|
|
||||||
case *LoadBalanceRequest_ClientStats:
|
|
||||||
s := proto.Size(x.ClientStats)
|
|
||||||
n += 1 // tag and wire
|
|
||||||
n += proto.SizeVarint(uint64(s))
|
|
||||||
n += s
|
|
||||||
case nil:
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
|
|
||||||
}
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
type InitialLoadBalanceRequest struct {
|
|
||||||
// Name of load balanced service (IE, balancer.service.com)
|
|
||||||
// length should be less than 256 bytes.
|
|
||||||
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
|
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
|
||||||
XXX_unrecognized []byte `json:"-"`
|
|
||||||
XXX_sizecache int32 `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *InitialLoadBalanceRequest) Reset() { *m = InitialLoadBalanceRequest{} }
|
|
||||||
func (m *InitialLoadBalanceRequest) String() string { return proto.CompactTextString(m) }
|
|
||||||
func (*InitialLoadBalanceRequest) ProtoMessage() {}
|
|
||||||
func (*InitialLoadBalanceRequest) Descriptor() ([]byte, []int) {
|
|
||||||
return fileDescriptor_messages_b81c731f0e83edbd, []int{3}
|
|
||||||
}
|
|
||||||
func (m *InitialLoadBalanceRequest) XXX_Unmarshal(b []byte) error {
|
|
||||||
return xxx_messageInfo_InitialLoadBalanceRequest.Unmarshal(m, b)
|
|
||||||
}
|
|
||||||
func (m *InitialLoadBalanceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
|
||||||
return xxx_messageInfo_InitialLoadBalanceRequest.Marshal(b, m, deterministic)
|
|
||||||
}
|
|
||||||
func (dst *InitialLoadBalanceRequest) XXX_Merge(src proto.Message) {
|
|
||||||
xxx_messageInfo_InitialLoadBalanceRequest.Merge(dst, src)
|
|
||||||
}
|
|
||||||
func (m *InitialLoadBalanceRequest) XXX_Size() int {
|
|
||||||
return xxx_messageInfo_InitialLoadBalanceRequest.Size(m)
|
|
||||||
}
|
|
||||||
func (m *InitialLoadBalanceRequest) XXX_DiscardUnknown() {
|
|
||||||
xxx_messageInfo_InitialLoadBalanceRequest.DiscardUnknown(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
var xxx_messageInfo_InitialLoadBalanceRequest proto.InternalMessageInfo
|
|
||||||
|
|
||||||
func (m *InitialLoadBalanceRequest) GetName() string {
|
|
||||||
if m != nil {
|
|
||||||
return m.Name
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// Contains client level statistics that are useful to load balancing. Each
|
|
||||||
// count except the timestamp should be reset to zero after reporting the stats.
|
|
||||||
type ClientStats struct {
|
|
||||||
// The timestamp of generating the report.
|
|
||||||
Timestamp *Timestamp `protobuf:"bytes,1,opt,name=timestamp" json:"timestamp,omitempty"`
|
|
||||||
// The total number of RPCs that started.
|
|
||||||
NumCallsStarted int64 `protobuf:"varint,2,opt,name=num_calls_started,json=numCallsStarted" json:"num_calls_started,omitempty"`
|
|
||||||
// The total number of RPCs that finished.
|
|
||||||
NumCallsFinished int64 `protobuf:"varint,3,opt,name=num_calls_finished,json=numCallsFinished" json:"num_calls_finished,omitempty"`
|
|
||||||
// The total number of RPCs that were dropped by the client because of rate
|
|
||||||
// limiting.
|
|
||||||
NumCallsFinishedWithDropForRateLimiting int64 `protobuf:"varint,4,opt,name=num_calls_finished_with_drop_for_rate_limiting,json=numCallsFinishedWithDropForRateLimiting" json:"num_calls_finished_with_drop_for_rate_limiting,omitempty"`
|
|
||||||
// The total number of RPCs that were dropped by the client because of load
|
|
||||||
// balancing.
|
|
||||||
NumCallsFinishedWithDropForLoadBalancing int64 `protobuf:"varint,5,opt,name=num_calls_finished_with_drop_for_load_balancing,json=numCallsFinishedWithDropForLoadBalancing" json:"num_calls_finished_with_drop_for_load_balancing,omitempty"`
|
|
||||||
// The total number of RPCs that failed to reach a server except dropped RPCs.
|
|
||||||
NumCallsFinishedWithClientFailedToSend int64 `protobuf:"varint,6,opt,name=num_calls_finished_with_client_failed_to_send,json=numCallsFinishedWithClientFailedToSend" json:"num_calls_finished_with_client_failed_to_send,omitempty"`
|
|
||||||
// The total number of RPCs that finished and are known to have been received
|
|
||||||
// by a server.
|
|
||||||
NumCallsFinishedKnownReceived int64 `protobuf:"varint,7,opt,name=num_calls_finished_known_received,json=numCallsFinishedKnownReceived" json:"num_calls_finished_known_received,omitempty"`
|
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
|
||||||
XXX_unrecognized []byte `json:"-"`
|
|
||||||
XXX_sizecache int32 `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *ClientStats) Reset() { *m = ClientStats{} }
|
|
||||||
func (m *ClientStats) String() string { return proto.CompactTextString(m) }
|
|
||||||
func (*ClientStats) ProtoMessage() {}
|
|
||||||
func (*ClientStats) Descriptor() ([]byte, []int) {
|
|
||||||
return fileDescriptor_messages_b81c731f0e83edbd, []int{4}
|
|
||||||
}
|
|
||||||
func (m *ClientStats) XXX_Unmarshal(b []byte) error {
|
|
||||||
return xxx_messageInfo_ClientStats.Unmarshal(m, b)
|
|
||||||
}
|
|
||||||
func (m *ClientStats) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
|
||||||
return xxx_messageInfo_ClientStats.Marshal(b, m, deterministic)
|
|
||||||
}
|
|
||||||
func (dst *ClientStats) XXX_Merge(src proto.Message) {
|
|
||||||
xxx_messageInfo_ClientStats.Merge(dst, src)
|
|
||||||
}
|
|
||||||
func (m *ClientStats) XXX_Size() int {
|
|
||||||
return xxx_messageInfo_ClientStats.Size(m)
|
|
||||||
}
|
|
||||||
func (m *ClientStats) XXX_DiscardUnknown() {
|
|
||||||
xxx_messageInfo_ClientStats.DiscardUnknown(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
var xxx_messageInfo_ClientStats proto.InternalMessageInfo
|
|
||||||
|
|
||||||
func (m *ClientStats) GetTimestamp() *Timestamp {
|
|
||||||
if m != nil {
|
|
||||||
return m.Timestamp
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *ClientStats) GetNumCallsStarted() int64 {
|
|
||||||
if m != nil {
|
|
||||||
return m.NumCallsStarted
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *ClientStats) GetNumCallsFinished() int64 {
|
|
||||||
if m != nil {
|
|
||||||
return m.NumCallsFinished
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *ClientStats) GetNumCallsFinishedWithDropForRateLimiting() int64 {
|
|
||||||
if m != nil {
|
|
||||||
return m.NumCallsFinishedWithDropForRateLimiting
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *ClientStats) GetNumCallsFinishedWithDropForLoadBalancing() int64 {
|
|
||||||
if m != nil {
|
|
||||||
return m.NumCallsFinishedWithDropForLoadBalancing
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *ClientStats) GetNumCallsFinishedWithClientFailedToSend() int64 {
|
|
||||||
if m != nil {
|
|
||||||
return m.NumCallsFinishedWithClientFailedToSend
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *ClientStats) GetNumCallsFinishedKnownReceived() int64 {
|
|
||||||
if m != nil {
|
|
||||||
return m.NumCallsFinishedKnownReceived
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type LoadBalanceResponse struct {
|
|
||||||
// Types that are valid to be assigned to LoadBalanceResponseType:
|
|
||||||
// *LoadBalanceResponse_InitialResponse
|
|
||||||
// *LoadBalanceResponse_ServerList
|
|
||||||
LoadBalanceResponseType isLoadBalanceResponse_LoadBalanceResponseType `protobuf_oneof:"load_balance_response_type"`
|
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
|
||||||
XXX_unrecognized []byte `json:"-"`
|
|
||||||
XXX_sizecache int32 `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *LoadBalanceResponse) Reset() { *m = LoadBalanceResponse{} }
|
|
||||||
func (m *LoadBalanceResponse) String() string { return proto.CompactTextString(m) }
|
|
||||||
func (*LoadBalanceResponse) ProtoMessage() {}
|
|
||||||
func (*LoadBalanceResponse) Descriptor() ([]byte, []int) {
|
|
||||||
return fileDescriptor_messages_b81c731f0e83edbd, []int{5}
|
|
||||||
}
|
|
||||||
func (m *LoadBalanceResponse) XXX_Unmarshal(b []byte) error {
|
|
||||||
return xxx_messageInfo_LoadBalanceResponse.Unmarshal(m, b)
|
|
||||||
}
|
|
||||||
func (m *LoadBalanceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
|
||||||
return xxx_messageInfo_LoadBalanceResponse.Marshal(b, m, deterministic)
|
|
||||||
}
|
|
||||||
func (dst *LoadBalanceResponse) XXX_Merge(src proto.Message) {
|
|
||||||
xxx_messageInfo_LoadBalanceResponse.Merge(dst, src)
|
|
||||||
}
|
|
||||||
func (m *LoadBalanceResponse) XXX_Size() int {
|
|
||||||
return xxx_messageInfo_LoadBalanceResponse.Size(m)
|
|
||||||
}
|
|
||||||
func (m *LoadBalanceResponse) XXX_DiscardUnknown() {
|
|
||||||
xxx_messageInfo_LoadBalanceResponse.DiscardUnknown(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
var xxx_messageInfo_LoadBalanceResponse proto.InternalMessageInfo
|
|
||||||
|
|
||||||
type isLoadBalanceResponse_LoadBalanceResponseType interface {
|
|
||||||
isLoadBalanceResponse_LoadBalanceResponseType()
|
|
||||||
}
|
|
||||||
|
|
||||||
type LoadBalanceResponse_InitialResponse struct {
|
|
||||||
InitialResponse *InitialLoadBalanceResponse `protobuf:"bytes,1,opt,name=initial_response,json=initialResponse,oneof"`
|
|
||||||
}
|
|
||||||
type LoadBalanceResponse_ServerList struct {
|
|
||||||
ServerList *ServerList `protobuf:"bytes,2,opt,name=server_list,json=serverList,oneof"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*LoadBalanceResponse_InitialResponse) isLoadBalanceResponse_LoadBalanceResponseType() {}
|
|
||||||
func (*LoadBalanceResponse_ServerList) isLoadBalanceResponse_LoadBalanceResponseType() {}
|
|
||||||
|
|
||||||
func (m *LoadBalanceResponse) GetLoadBalanceResponseType() isLoadBalanceResponse_LoadBalanceResponseType {
|
|
||||||
if m != nil {
|
|
||||||
return m.LoadBalanceResponseType
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *LoadBalanceResponse) GetInitialResponse() *InitialLoadBalanceResponse {
|
|
||||||
if x, ok := m.GetLoadBalanceResponseType().(*LoadBalanceResponse_InitialResponse); ok {
|
|
||||||
return x.InitialResponse
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *LoadBalanceResponse) GetServerList() *ServerList {
|
|
||||||
if x, ok := m.GetLoadBalanceResponseType().(*LoadBalanceResponse_ServerList); ok {
|
|
||||||
return x.ServerList
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX_OneofFuncs is for the internal use of the proto package.
|
|
||||||
func (*LoadBalanceResponse) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
|
|
||||||
return _LoadBalanceResponse_OneofMarshaler, _LoadBalanceResponse_OneofUnmarshaler, _LoadBalanceResponse_OneofSizer, []interface{}{
|
|
||||||
(*LoadBalanceResponse_InitialResponse)(nil),
|
|
||||||
(*LoadBalanceResponse_ServerList)(nil),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func _LoadBalanceResponse_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
|
|
||||||
m := msg.(*LoadBalanceResponse)
|
|
||||||
// load_balance_response_type
|
|
||||||
switch x := m.LoadBalanceResponseType.(type) {
|
|
||||||
case *LoadBalanceResponse_InitialResponse:
|
|
||||||
b.EncodeVarint(1<<3 | proto.WireBytes)
|
|
||||||
if err := b.EncodeMessage(x.InitialResponse); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
case *LoadBalanceResponse_ServerList:
|
|
||||||
b.EncodeVarint(2<<3 | proto.WireBytes)
|
|
||||||
if err := b.EncodeMessage(x.ServerList); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
case nil:
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("LoadBalanceResponse.LoadBalanceResponseType has unexpected type %T", x)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func _LoadBalanceResponse_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
|
|
||||||
m := msg.(*LoadBalanceResponse)
|
|
||||||
switch tag {
|
|
||||||
case 1: // load_balance_response_type.initial_response
|
|
||||||
if wire != proto.WireBytes {
|
|
||||||
return true, proto.ErrInternalBadWireType
|
|
||||||
}
|
|
||||||
msg := new(InitialLoadBalanceResponse)
|
|
||||||
err := b.DecodeMessage(msg)
|
|
||||||
m.LoadBalanceResponseType = &LoadBalanceResponse_InitialResponse{msg}
|
|
||||||
return true, err
|
|
||||||
case 2: // load_balance_response_type.server_list
|
|
||||||
if wire != proto.WireBytes {
|
|
||||||
return true, proto.ErrInternalBadWireType
|
|
||||||
}
|
|
||||||
msg := new(ServerList)
|
|
||||||
err := b.DecodeMessage(msg)
|
|
||||||
m.LoadBalanceResponseType = &LoadBalanceResponse_ServerList{msg}
|
|
||||||
return true, err
|
|
||||||
default:
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func _LoadBalanceResponse_OneofSizer(msg proto.Message) (n int) {
|
|
||||||
m := msg.(*LoadBalanceResponse)
|
|
||||||
// load_balance_response_type
|
|
||||||
switch x := m.LoadBalanceResponseType.(type) {
|
|
||||||
case *LoadBalanceResponse_InitialResponse:
|
|
||||||
s := proto.Size(x.InitialResponse)
|
|
||||||
n += 1 // tag and wire
|
|
||||||
n += proto.SizeVarint(uint64(s))
|
|
||||||
n += s
|
|
||||||
case *LoadBalanceResponse_ServerList:
|
|
||||||
s := proto.Size(x.ServerList)
|
|
||||||
n += 1 // tag and wire
|
|
||||||
n += proto.SizeVarint(uint64(s))
|
|
||||||
n += s
|
|
||||||
case nil:
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
|
|
||||||
}
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
type InitialLoadBalanceResponse struct {
|
|
||||||
// This is an application layer redirect that indicates the client should use
|
|
||||||
// the specified server for load balancing. When this field is non-empty in
|
|
||||||
// the response, the client should open a separate connection to the
|
|
||||||
// load_balancer_delegate and call the BalanceLoad method. Its length should
|
|
||||||
// be less than 64 bytes.
|
|
||||||
LoadBalancerDelegate string `protobuf:"bytes,1,opt,name=load_balancer_delegate,json=loadBalancerDelegate" json:"load_balancer_delegate,omitempty"`
|
|
||||||
// This interval defines how often the client should send the client stats
|
|
||||||
// to the load balancer. Stats should only be reported when the duration is
|
|
||||||
// positive.
|
|
||||||
ClientStatsReportInterval *Duration `protobuf:"bytes,2,opt,name=client_stats_report_interval,json=clientStatsReportInterval" json:"client_stats_report_interval,omitempty"`
|
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
|
||||||
XXX_unrecognized []byte `json:"-"`
|
|
||||||
XXX_sizecache int32 `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *InitialLoadBalanceResponse) Reset() { *m = InitialLoadBalanceResponse{} }
|
|
||||||
func (m *InitialLoadBalanceResponse) String() string { return proto.CompactTextString(m) }
|
|
||||||
func (*InitialLoadBalanceResponse) ProtoMessage() {}
|
|
||||||
func (*InitialLoadBalanceResponse) Descriptor() ([]byte, []int) {
|
|
||||||
return fileDescriptor_messages_b81c731f0e83edbd, []int{6}
|
|
||||||
}
|
|
||||||
func (m *InitialLoadBalanceResponse) XXX_Unmarshal(b []byte) error {
|
|
||||||
return xxx_messageInfo_InitialLoadBalanceResponse.Unmarshal(m, b)
|
|
||||||
}
|
|
||||||
func (m *InitialLoadBalanceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
|
||||||
return xxx_messageInfo_InitialLoadBalanceResponse.Marshal(b, m, deterministic)
|
|
||||||
}
|
|
||||||
func (dst *InitialLoadBalanceResponse) XXX_Merge(src proto.Message) {
|
|
||||||
xxx_messageInfo_InitialLoadBalanceResponse.Merge(dst, src)
|
|
||||||
}
|
|
||||||
func (m *InitialLoadBalanceResponse) XXX_Size() int {
|
|
||||||
return xxx_messageInfo_InitialLoadBalanceResponse.Size(m)
|
|
||||||
}
|
|
||||||
func (m *InitialLoadBalanceResponse) XXX_DiscardUnknown() {
|
|
||||||
xxx_messageInfo_InitialLoadBalanceResponse.DiscardUnknown(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
var xxx_messageInfo_InitialLoadBalanceResponse proto.InternalMessageInfo
|
|
||||||
|
|
||||||
func (m *InitialLoadBalanceResponse) GetLoadBalancerDelegate() string {
|
|
||||||
if m != nil {
|
|
||||||
return m.LoadBalancerDelegate
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *InitialLoadBalanceResponse) GetClientStatsReportInterval() *Duration {
|
|
||||||
if m != nil {
|
|
||||||
return m.ClientStatsReportInterval
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type ServerList struct {
|
|
||||||
// Contains a list of servers selected by the load balancer. The list will
|
|
||||||
// be updated when server resolutions change or as needed to balance load
|
|
||||||
// across more servers. The client should consume the server list in order
|
|
||||||
// unless instructed otherwise via the client_config.
|
|
||||||
Servers []*Server `protobuf:"bytes,1,rep,name=servers" json:"servers,omitempty"`
|
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
|
||||||
XXX_unrecognized []byte `json:"-"`
|
|
||||||
XXX_sizecache int32 `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *ServerList) Reset() { *m = ServerList{} }
|
|
||||||
func (m *ServerList) String() string { return proto.CompactTextString(m) }
|
|
||||||
func (*ServerList) ProtoMessage() {}
|
|
||||||
func (*ServerList) Descriptor() ([]byte, []int) {
|
|
||||||
return fileDescriptor_messages_b81c731f0e83edbd, []int{7}
|
|
||||||
}
|
|
||||||
func (m *ServerList) XXX_Unmarshal(b []byte) error {
|
|
||||||
return xxx_messageInfo_ServerList.Unmarshal(m, b)
|
|
||||||
}
|
|
||||||
func (m *ServerList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
|
||||||
return xxx_messageInfo_ServerList.Marshal(b, m, deterministic)
|
|
||||||
}
|
|
||||||
func (dst *ServerList) XXX_Merge(src proto.Message) {
|
|
||||||
xxx_messageInfo_ServerList.Merge(dst, src)
|
|
||||||
}
|
|
||||||
func (m *ServerList) XXX_Size() int {
|
|
||||||
return xxx_messageInfo_ServerList.Size(m)
|
|
||||||
}
|
|
||||||
func (m *ServerList) XXX_DiscardUnknown() {
|
|
||||||
xxx_messageInfo_ServerList.DiscardUnknown(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
var xxx_messageInfo_ServerList proto.InternalMessageInfo
|
|
||||||
|
|
||||||
func (m *ServerList) GetServers() []*Server {
|
|
||||||
if m != nil {
|
|
||||||
return m.Servers
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Contains server information. When none of the [drop_for_*] fields are true,
|
|
||||||
// use the other fields. When drop_for_rate_limiting is true, ignore all other
|
|
||||||
// fields. Use drop_for_load_balancing only when it is true and
|
|
||||||
// drop_for_rate_limiting is false.
|
|
||||||
type Server struct {
|
|
||||||
// A resolved address for the server, serialized in network-byte-order. It may
|
|
||||||
// either be an IPv4 or IPv6 address.
|
|
||||||
IpAddress []byte `protobuf:"bytes,1,opt,name=ip_address,json=ipAddress,proto3" json:"ip_address,omitempty"`
|
|
||||||
// A resolved port number for the server.
|
|
||||||
Port int32 `protobuf:"varint,2,opt,name=port" json:"port,omitempty"`
|
|
||||||
// An opaque but printable token given to the frontend for each pick. All
|
|
||||||
// frontend requests for that pick must include the token in its initial
|
|
||||||
// metadata. The token is used by the backend to verify the request and to
|
|
||||||
// allow the backend to report load to the gRPC LB system.
|
|
||||||
//
|
|
||||||
// Its length is variable but less than 50 bytes.
|
|
||||||
LoadBalanceToken string `protobuf:"bytes,3,opt,name=load_balance_token,json=loadBalanceToken" json:"load_balance_token,omitempty"`
|
|
||||||
// Indicates whether this particular request should be dropped by the client
|
|
||||||
// for rate limiting.
|
|
||||||
DropForRateLimiting bool `protobuf:"varint,4,opt,name=drop_for_rate_limiting,json=dropForRateLimiting" json:"drop_for_rate_limiting,omitempty"`
|
|
||||||
// Indicates whether this particular request should be dropped by the client
|
|
||||||
// for load balancing.
|
|
||||||
DropForLoadBalancing bool `protobuf:"varint,5,opt,name=drop_for_load_balancing,json=dropForLoadBalancing" json:"drop_for_load_balancing,omitempty"`
|
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
|
||||||
XXX_unrecognized []byte `json:"-"`
|
|
||||||
XXX_sizecache int32 `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Server) Reset() { *m = Server{} }
|
|
||||||
func (m *Server) String() string { return proto.CompactTextString(m) }
|
|
||||||
func (*Server) ProtoMessage() {}
|
|
||||||
func (*Server) Descriptor() ([]byte, []int) {
|
|
||||||
return fileDescriptor_messages_b81c731f0e83edbd, []int{8}
|
|
||||||
}
|
|
||||||
func (m *Server) XXX_Unmarshal(b []byte) error {
|
|
||||||
return xxx_messageInfo_Server.Unmarshal(m, b)
|
|
||||||
}
|
|
||||||
func (m *Server) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
|
||||||
return xxx_messageInfo_Server.Marshal(b, m, deterministic)
|
|
||||||
}
|
|
||||||
func (dst *Server) XXX_Merge(src proto.Message) {
|
|
||||||
xxx_messageInfo_Server.Merge(dst, src)
|
|
||||||
}
|
|
||||||
func (m *Server) XXX_Size() int {
|
|
||||||
return xxx_messageInfo_Server.Size(m)
|
|
||||||
}
|
|
||||||
func (m *Server) XXX_DiscardUnknown() {
|
|
||||||
xxx_messageInfo_Server.DiscardUnknown(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
var xxx_messageInfo_Server proto.InternalMessageInfo
|
|
||||||
|
|
||||||
func (m *Server) GetIpAddress() []byte {
|
|
||||||
if m != nil {
|
|
||||||
return m.IpAddress
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Server) GetPort() int32 {
|
|
||||||
if m != nil {
|
|
||||||
return m.Port
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Server) GetLoadBalanceToken() string {
|
|
||||||
if m != nil {
|
|
||||||
return m.LoadBalanceToken
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Server) GetDropForRateLimiting() bool {
|
|
||||||
if m != nil {
|
|
||||||
return m.DropForRateLimiting
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Server) GetDropForLoadBalancing() bool {
|
|
||||||
if m != nil {
|
|
||||||
return m.DropForLoadBalancing
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
proto.RegisterType((*Duration)(nil), "grpc.lb.v1.Duration")
|
|
||||||
proto.RegisterType((*Timestamp)(nil), "grpc.lb.v1.Timestamp")
|
|
||||||
proto.RegisterType((*LoadBalanceRequest)(nil), "grpc.lb.v1.LoadBalanceRequest")
|
|
||||||
proto.RegisterType((*InitialLoadBalanceRequest)(nil), "grpc.lb.v1.InitialLoadBalanceRequest")
|
|
||||||
proto.RegisterType((*ClientStats)(nil), "grpc.lb.v1.ClientStats")
|
|
||||||
proto.RegisterType((*LoadBalanceResponse)(nil), "grpc.lb.v1.LoadBalanceResponse")
|
|
||||||
proto.RegisterType((*InitialLoadBalanceResponse)(nil), "grpc.lb.v1.InitialLoadBalanceResponse")
|
|
||||||
proto.RegisterType((*ServerList)(nil), "grpc.lb.v1.ServerList")
|
|
||||||
proto.RegisterType((*Server)(nil), "grpc.lb.v1.Server")
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
proto.RegisterFile("grpc_lb_v1/messages/messages.proto", fileDescriptor_messages_b81c731f0e83edbd)
|
|
||||||
}
|
|
||||||
|
|
||||||
var fileDescriptor_messages_b81c731f0e83edbd = []byte{
|
|
||||||
// 731 bytes of a gzipped FileDescriptorProto
|
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0xdd, 0x4e, 0x1b, 0x39,
|
|
||||||
0x14, 0x26, 0x9b, 0x00, 0xc9, 0x09, 0x5a, 0xb2, 0x26, 0x0b, 0x81, 0x05, 0x89, 0x1d, 0x69, 0xd9,
|
|
||||||
0x68, 0xc5, 0x4e, 0x04, 0xd9, 0xbd, 0xe8, 0xcf, 0x45, 0x1b, 0x10, 0x0a, 0x2d, 0x17, 0x95, 0x43,
|
|
||||||
0x55, 0xa9, 0x52, 0x65, 0x39, 0x19, 0x33, 0x58, 0x38, 0xf6, 0xd4, 0x76, 0x82, 0xfa, 0x08, 0x7d,
|
|
||||||
0x94, 0x3e, 0x46, 0xd5, 0x67, 0xe8, 0xfb, 0x54, 0xe3, 0x99, 0xc9, 0x0c, 0x10, 0x40, 0xbd, 0x89,
|
|
||||||
0xec, 0xe3, 0xef, 0x7c, 0xdf, 0xf1, 0x89, 0xbf, 0x33, 0xe0, 0x85, 0x3a, 0x1a, 0x11, 0x31, 0x24,
|
|
||||||
0xd3, 0x83, 0xce, 0x98, 0x19, 0x43, 0x43, 0x66, 0x66, 0x0b, 0x3f, 0xd2, 0xca, 0x2a, 0x04, 0x31,
|
|
||||||
0xc6, 0x17, 0x43, 0x7f, 0x7a, 0xe0, 0x3d, 0x85, 0xea, 0xf1, 0x44, 0x53, 0xcb, 0x95, 0x44, 0x2d,
|
|
||||||
0x58, 0x36, 0x6c, 0xa4, 0x64, 0x60, 0x5a, 0xa5, 0xdd, 0x52, 0xbb, 0x8c, 0xb3, 0x2d, 0x6a, 0xc2,
|
|
||||||
0xa2, 0xa4, 0x52, 0x99, 0xd6, 0x2f, 0xbb, 0xa5, 0xf6, 0x22, 0x4e, 0x36, 0xde, 0x33, 0xa8, 0x9d,
|
|
||||||
0xf3, 0x31, 0x33, 0x96, 0x8e, 0xa3, 0x9f, 0x4e, 0xfe, 0x5a, 0x02, 0x74, 0xa6, 0x68, 0xd0, 0xa3,
|
|
||||||
0x82, 0xca, 0x11, 0xc3, 0xec, 0xe3, 0x84, 0x19, 0x8b, 0xde, 0xc0, 0x2a, 0x97, 0xdc, 0x72, 0x2a,
|
|
||||||
0x88, 0x4e, 0x42, 0x8e, 0xae, 0x7e, 0xf8, 0x97, 0x9f, 0x57, 0xed, 0x9f, 0x26, 0x90, 0xbb, 0xf9,
|
|
||||||
0xfd, 0x05, 0xfc, 0x6b, 0x9a, 0x9f, 0x31, 0x3e, 0x87, 0x95, 0x91, 0xe0, 0x4c, 0x5a, 0x62, 0x2c,
|
|
||||||
0xb5, 0x49, 0x15, 0xf5, 0xc3, 0x8d, 0x22, 0xdd, 0x91, 0x3b, 0x1f, 0xc4, 0xc7, 0xfd, 0x05, 0x5c,
|
|
||||||
0x1f, 0xe5, 0xdb, 0xde, 0x1f, 0xb0, 0x29, 0x14, 0x0d, 0xc8, 0x30, 0x91, 0xc9, 0x8a, 0x22, 0xf6,
|
|
||||||
0x53, 0xc4, 0xbc, 0x0e, 0x6c, 0xde, 0x5b, 0x09, 0x42, 0x50, 0x91, 0x74, 0xcc, 0x5c, 0xf9, 0x35,
|
|
||||||
0xec, 0xd6, 0xde, 0xe7, 0x0a, 0xd4, 0x0b, 0x62, 0xa8, 0x0b, 0x35, 0x9b, 0x75, 0x30, 0xbd, 0xe7,
|
|
||||||
0xef, 0xc5, 0xc2, 0x66, 0xed, 0xc5, 0x39, 0x0e, 0xfd, 0x03, 0xbf, 0xc9, 0xc9, 0x98, 0x8c, 0xa8,
|
|
||||||
0x10, 0x26, 0xbe, 0x93, 0xb6, 0x2c, 0x70, 0xb7, 0x2a, 0xe3, 0x55, 0x39, 0x19, 0x1f, 0xc5, 0xf1,
|
|
||||||
0x41, 0x12, 0x46, 0xfb, 0x80, 0x72, 0xec, 0x05, 0x97, 0xdc, 0x5c, 0xb2, 0xa0, 0x55, 0x76, 0xe0,
|
|
||||||
0x46, 0x06, 0x3e, 0x49, 0xe3, 0x88, 0x80, 0x7f, 0x17, 0x4d, 0xae, 0xb9, 0xbd, 0x24, 0x81, 0x56,
|
|
||||||
0x11, 0xb9, 0x50, 0x9a, 0x68, 0x6a, 0x19, 0x11, 0x7c, 0xcc, 0x2d, 0x97, 0x61, 0xab, 0xe2, 0x98,
|
|
||||||
0xfe, 0xbe, 0xcd, 0xf4, 0x8e, 0xdb, 0xcb, 0x63, 0xad, 0xa2, 0x13, 0xa5, 0x31, 0xb5, 0xec, 0x2c,
|
|
||||||
0x85, 0x23, 0x0a, 0x9d, 0x47, 0x05, 0x0a, 0xed, 0x8e, 0x15, 0x16, 0x9d, 0x42, 0xfb, 0x01, 0x85,
|
|
||||||
0xbc, 0xf7, 0xb1, 0xc4, 0x07, 0xf8, 0xf7, 0x3e, 0x89, 0xf4, 0x19, 0x5c, 0x50, 0x2e, 0x58, 0x40,
|
|
||||||
0xac, 0x22, 0x86, 0xc9, 0xa0, 0xb5, 0xe4, 0x04, 0xf6, 0xe6, 0x09, 0x24, 0x7f, 0xd5, 0x89, 0xc3,
|
|
||||||
0x9f, 0xab, 0x01, 0x93, 0x01, 0xea, 0xc3, 0x9f, 0x73, 0xe8, 0xaf, 0xa4, 0xba, 0x96, 0x44, 0xb3,
|
|
||||||
0x11, 0xe3, 0x53, 0x16, 0xb4, 0x96, 0x1d, 0xe5, 0xce, 0x6d, 0xca, 0xd7, 0x31, 0x0a, 0xa7, 0x20,
|
|
||||||
0xef, 0x5b, 0x09, 0xd6, 0x6e, 0x3c, 0x1b, 0x13, 0x29, 0x69, 0x18, 0x1a, 0x40, 0x23, 0x77, 0x40,
|
|
||||||
0x12, 0x4b, 0x9f, 0xc6, 0xde, 0x63, 0x16, 0x48, 0xd0, 0xfd, 0x05, 0xbc, 0x3a, 0xf3, 0x40, 0x4a,
|
|
||||||
0xfa, 0x04, 0xea, 0x86, 0xe9, 0x29, 0xd3, 0x44, 0x70, 0x63, 0x53, 0x0f, 0xac, 0x17, 0xf9, 0x06,
|
|
||||||
0xee, 0xf8, 0x8c, 0x3b, 0x0f, 0x81, 0x99, 0xed, 0x7a, 0xdb, 0xb0, 0x75, 0xcb, 0x01, 0x09, 0x67,
|
|
||||||
0x62, 0x81, 0x2f, 0x25, 0xd8, 0xba, 0xbf, 0x14, 0xf4, 0x1f, 0xac, 0x17, 0x93, 0x35, 0x09, 0x98,
|
|
||||||
0x60, 0x21, 0xb5, 0x99, 0x2d, 0x9a, 0x22, 0x4f, 0xd2, 0xc7, 0xe9, 0x19, 0x7a, 0x0b, 0xdb, 0x45,
|
|
||||||
0xcb, 0x12, 0xcd, 0x22, 0xa5, 0x2d, 0xe1, 0xd2, 0x32, 0x3d, 0xa5, 0x22, 0x2d, 0xbf, 0x59, 0x2c,
|
|
||||||
0x3f, 0x1b, 0x62, 0x78, 0xb3, 0xe0, 0x5e, 0xec, 0xf2, 0x4e, 0xd3, 0x34, 0xef, 0x05, 0x40, 0x7e,
|
|
||||||
0x4b, 0xb4, 0x1f, 0x0f, 0xac, 0x78, 0x17, 0x0f, 0xac, 0x72, 0xbb, 0x7e, 0x88, 0xee, 0xb6, 0x03,
|
|
||||||
0x67, 0x90, 0x57, 0x95, 0x6a, 0xb9, 0x51, 0xf1, 0xbe, 0x97, 0x60, 0x29, 0x39, 0x41, 0x3b, 0x00,
|
|
||||||
0x3c, 0x22, 0x34, 0x08, 0x34, 0x33, 0xc9, 0xc8, 0x5b, 0xc1, 0x35, 0x1e, 0xbd, 0x4c, 0x02, 0xb1,
|
|
||||||
0xfb, 0x63, 0xed, 0x74, 0xe6, 0xb9, 0x75, 0x6c, 0xc6, 0x1b, 0x9d, 0xb4, 0xea, 0x8a, 0x49, 0x67,
|
|
||||||
0xc6, 0x1a, 0x6e, 0x14, 0x1a, 0x71, 0x1e, 0xc7, 0x51, 0x17, 0xd6, 0x1f, 0x30, 0x5d, 0x15, 0xaf,
|
|
||||||
0x05, 0x73, 0x0c, 0xf6, 0x3f, 0x6c, 0x3c, 0x64, 0xa4, 0x2a, 0x6e, 0x06, 0x73, 0x4c, 0xd3, 0xeb,
|
|
||||||
0xbe, 0x3f, 0x08, 0x95, 0x0a, 0x05, 0xf3, 0x43, 0x25, 0xa8, 0x0c, 0x7d, 0xa5, 0xc3, 0x4e, 0xdc,
|
|
||||||
0x0d, 0xf7, 0x23, 0x86, 0x9d, 0x39, 0x5f, 0x95, 0xe1, 0x92, 0xfb, 0x9a, 0x74, 0x7f, 0x04, 0x00,
|
|
||||||
0x00, 0xff, 0xff, 0x8e, 0xd0, 0x70, 0xb7, 0x73, 0x06, 0x00, 0x00,
|
|
||||||
}
|
|
155
vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/messages/messages.proto
generated
vendored
155
vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/messages/messages.proto
generated
vendored
@ -1,155 +0,0 @@
|
|||||||
// Copyright 2016 gRPC authors.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
package grpc.lb.v1;
|
|
||||||
option go_package = "google.golang.org/grpc/grpclb/grpc_lb_v1/messages";
|
|
||||||
|
|
||||||
message Duration {
|
|
||||||
// Signed seconds of the span of time. Must be from -315,576,000,000
|
|
||||||
// to +315,576,000,000 inclusive.
|
|
||||||
int64 seconds = 1;
|
|
||||||
|
|
||||||
// Signed fractions of a second at nanosecond resolution of the span
|
|
||||||
// of time. Durations less than one second are represented with a 0
|
|
||||||
// `seconds` field and a positive or negative `nanos` field. For durations
|
|
||||||
// of one second or more, a non-zero value for the `nanos` field must be
|
|
||||||
// of the same sign as the `seconds` field. Must be from -999,999,999
|
|
||||||
// to +999,999,999 inclusive.
|
|
||||||
int32 nanos = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message Timestamp {
|
|
||||||
// Represents seconds of UTC time since Unix epoch
|
|
||||||
// 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
|
|
||||||
// 9999-12-31T23:59:59Z inclusive.
|
|
||||||
int64 seconds = 1;
|
|
||||||
|
|
||||||
// Non-negative fractions of a second at nanosecond resolution. Negative
|
|
||||||
// second values with fractions must still have non-negative nanos values
|
|
||||||
// that count forward in time. Must be from 0 to 999,999,999
|
|
||||||
// inclusive.
|
|
||||||
int32 nanos = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message LoadBalanceRequest {
|
|
||||||
oneof load_balance_request_type {
|
|
||||||
// This message should be sent on the first request to the load balancer.
|
|
||||||
InitialLoadBalanceRequest initial_request = 1;
|
|
||||||
|
|
||||||
// The client stats should be periodically reported to the load balancer
|
|
||||||
// based on the duration defined in the InitialLoadBalanceResponse.
|
|
||||||
ClientStats client_stats = 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
message InitialLoadBalanceRequest {
|
|
||||||
// Name of load balanced service (IE, balancer.service.com)
|
|
||||||
// length should be less than 256 bytes.
|
|
||||||
string name = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Contains client level statistics that are useful to load balancing. Each
|
|
||||||
// count except the timestamp should be reset to zero after reporting the stats.
|
|
||||||
message ClientStats {
|
|
||||||
// The timestamp of generating the report.
|
|
||||||
Timestamp timestamp = 1;
|
|
||||||
|
|
||||||
// The total number of RPCs that started.
|
|
||||||
int64 num_calls_started = 2;
|
|
||||||
|
|
||||||
// The total number of RPCs that finished.
|
|
||||||
int64 num_calls_finished = 3;
|
|
||||||
|
|
||||||
// The total number of RPCs that were dropped by the client because of rate
|
|
||||||
// limiting.
|
|
||||||
int64 num_calls_finished_with_drop_for_rate_limiting = 4;
|
|
||||||
|
|
||||||
// The total number of RPCs that were dropped by the client because of load
|
|
||||||
// balancing.
|
|
||||||
int64 num_calls_finished_with_drop_for_load_balancing = 5;
|
|
||||||
|
|
||||||
// The total number of RPCs that failed to reach a server except dropped RPCs.
|
|
||||||
int64 num_calls_finished_with_client_failed_to_send = 6;
|
|
||||||
|
|
||||||
// The total number of RPCs that finished and are known to have been received
|
|
||||||
// by a server.
|
|
||||||
int64 num_calls_finished_known_received = 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
message LoadBalanceResponse {
|
|
||||||
oneof load_balance_response_type {
|
|
||||||
// This message should be sent on the first response to the client.
|
|
||||||
InitialLoadBalanceResponse initial_response = 1;
|
|
||||||
|
|
||||||
// Contains the list of servers selected by the load balancer. The client
|
|
||||||
// should send requests to these servers in the specified order.
|
|
||||||
ServerList server_list = 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
message InitialLoadBalanceResponse {
|
|
||||||
// This is an application layer redirect that indicates the client should use
|
|
||||||
// the specified server for load balancing. When this field is non-empty in
|
|
||||||
// the response, the client should open a separate connection to the
|
|
||||||
// load_balancer_delegate and call the BalanceLoad method. Its length should
|
|
||||||
// be less than 64 bytes.
|
|
||||||
string load_balancer_delegate = 1;
|
|
||||||
|
|
||||||
// This interval defines how often the client should send the client stats
|
|
||||||
// to the load balancer. Stats should only be reported when the duration is
|
|
||||||
// positive.
|
|
||||||
Duration client_stats_report_interval = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ServerList {
|
|
||||||
// Contains a list of servers selected by the load balancer. The list will
|
|
||||||
// be updated when server resolutions change or as needed to balance load
|
|
||||||
// across more servers. The client should consume the server list in order
|
|
||||||
// unless instructed otherwise via the client_config.
|
|
||||||
repeated Server servers = 1;
|
|
||||||
|
|
||||||
// Was google.protobuf.Duration expiration_interval.
|
|
||||||
reserved 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Contains server information. When none of the [drop_for_*] fields are true,
|
|
||||||
// use the other fields. When drop_for_rate_limiting is true, ignore all other
|
|
||||||
// fields. Use drop_for_load_balancing only when it is true and
|
|
||||||
// drop_for_rate_limiting is false.
|
|
||||||
message Server {
|
|
||||||
// A resolved address for the server, serialized in network-byte-order. It may
|
|
||||||
// either be an IPv4 or IPv6 address.
|
|
||||||
bytes ip_address = 1;
|
|
||||||
|
|
||||||
// A resolved port number for the server.
|
|
||||||
int32 port = 2;
|
|
||||||
|
|
||||||
// An opaque but printable token given to the frontend for each pick. All
|
|
||||||
// frontend requests for that pick must include the token in its initial
|
|
||||||
// metadata. The token is used by the backend to verify the request and to
|
|
||||||
// allow the backend to report load to the gRPC LB system.
|
|
||||||
//
|
|
||||||
// Its length is variable but less than 50 bytes.
|
|
||||||
string load_balance_token = 3;
|
|
||||||
|
|
||||||
// Indicates whether this particular request should be dropped by the client
|
|
||||||
// for rate limiting.
|
|
||||||
bool drop_for_rate_limiting = 4;
|
|
||||||
|
|
||||||
// Indicates whether this particular request should be dropped by the client
|
|
||||||
// for load balancing.
|
|
||||||
bool drop_for_load_balancing = 5;
|
|
||||||
}
|
|
159
vendor/google.golang.org/grpc/grpclb_picker.go
generated
vendored
159
vendor/google.golang.org/grpc/grpclb_picker.go
generated
vendored
@ -1,159 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* Copyright 2017 gRPC authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
package grpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
"sync/atomic"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
"google.golang.org/grpc/balancer"
|
|
||||||
"google.golang.org/grpc/codes"
|
|
||||||
lbpb "google.golang.org/grpc/grpclb/grpc_lb_v1/messages"
|
|
||||||
"google.golang.org/grpc/status"
|
|
||||||
)
|
|
||||||
|
|
||||||
type rpcStats struct {
|
|
||||||
NumCallsStarted int64
|
|
||||||
NumCallsFinished int64
|
|
||||||
NumCallsFinishedWithDropForRateLimiting int64
|
|
||||||
NumCallsFinishedWithDropForLoadBalancing int64
|
|
||||||
NumCallsFinishedWithClientFailedToSend int64
|
|
||||||
NumCallsFinishedKnownReceived int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// toClientStats converts rpcStats to lbpb.ClientStats, and clears rpcStats.
|
|
||||||
func (s *rpcStats) toClientStats() *lbpb.ClientStats {
|
|
||||||
stats := &lbpb.ClientStats{
|
|
||||||
NumCallsStarted: atomic.SwapInt64(&s.NumCallsStarted, 0),
|
|
||||||
NumCallsFinished: atomic.SwapInt64(&s.NumCallsFinished, 0),
|
|
||||||
NumCallsFinishedWithDropForRateLimiting: atomic.SwapInt64(&s.NumCallsFinishedWithDropForRateLimiting, 0),
|
|
||||||
NumCallsFinishedWithDropForLoadBalancing: atomic.SwapInt64(&s.NumCallsFinishedWithDropForLoadBalancing, 0),
|
|
||||||
NumCallsFinishedWithClientFailedToSend: atomic.SwapInt64(&s.NumCallsFinishedWithClientFailedToSend, 0),
|
|
||||||
NumCallsFinishedKnownReceived: atomic.SwapInt64(&s.NumCallsFinishedKnownReceived, 0),
|
|
||||||
}
|
|
||||||
return stats
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *rpcStats) dropForRateLimiting() {
|
|
||||||
atomic.AddInt64(&s.NumCallsStarted, 1)
|
|
||||||
atomic.AddInt64(&s.NumCallsFinishedWithDropForRateLimiting, 1)
|
|
||||||
atomic.AddInt64(&s.NumCallsFinished, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *rpcStats) dropForLoadBalancing() {
|
|
||||||
atomic.AddInt64(&s.NumCallsStarted, 1)
|
|
||||||
atomic.AddInt64(&s.NumCallsFinishedWithDropForLoadBalancing, 1)
|
|
||||||
atomic.AddInt64(&s.NumCallsFinished, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *rpcStats) failedToSend() {
|
|
||||||
atomic.AddInt64(&s.NumCallsStarted, 1)
|
|
||||||
atomic.AddInt64(&s.NumCallsFinishedWithClientFailedToSend, 1)
|
|
||||||
atomic.AddInt64(&s.NumCallsFinished, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *rpcStats) knownReceived() {
|
|
||||||
atomic.AddInt64(&s.NumCallsStarted, 1)
|
|
||||||
atomic.AddInt64(&s.NumCallsFinishedKnownReceived, 1)
|
|
||||||
atomic.AddInt64(&s.NumCallsFinished, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
type errPicker struct {
|
|
||||||
// Pick always returns this err.
|
|
||||||
err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *errPicker) Pick(ctx context.Context, opts balancer.PickOptions) (balancer.SubConn, func(balancer.DoneInfo), error) {
|
|
||||||
return nil, nil, p.err
|
|
||||||
}
|
|
||||||
|
|
||||||
// rrPicker does roundrobin on subConns. It's typically used when there's no
|
|
||||||
// response from remote balancer, and grpclb falls back to the resolved
|
|
||||||
// backends.
|
|
||||||
//
|
|
||||||
// It guaranteed that len(subConns) > 0.
|
|
||||||
type rrPicker struct {
|
|
||||||
mu sync.Mutex
|
|
||||||
subConns []balancer.SubConn // The subConns that were READY when taking the snapshot.
|
|
||||||
subConnsNext int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *rrPicker) Pick(ctx context.Context, opts balancer.PickOptions) (balancer.SubConn, func(balancer.DoneInfo), error) {
|
|
||||||
p.mu.Lock()
|
|
||||||
defer p.mu.Unlock()
|
|
||||||
sc := p.subConns[p.subConnsNext]
|
|
||||||
p.subConnsNext = (p.subConnsNext + 1) % len(p.subConns)
|
|
||||||
return sc, nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// lbPicker does two layers of picks:
|
|
||||||
//
|
|
||||||
// First layer: roundrobin on all servers in serverList, including drops and backends.
|
|
||||||
// - If it picks a drop, the RPC will fail as being dropped.
|
|
||||||
// - If it picks a backend, do a second layer pick to pick the real backend.
|
|
||||||
//
|
|
||||||
// Second layer: roundrobin on all READY backends.
|
|
||||||
//
|
|
||||||
// It's guaranteed that len(serverList) > 0.
|
|
||||||
type lbPicker struct {
|
|
||||||
mu sync.Mutex
|
|
||||||
serverList []*lbpb.Server
|
|
||||||
serverListNext int
|
|
||||||
subConns []balancer.SubConn // The subConns that were READY when taking the snapshot.
|
|
||||||
subConnsNext int
|
|
||||||
|
|
||||||
stats *rpcStats
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *lbPicker) Pick(ctx context.Context, opts balancer.PickOptions) (balancer.SubConn, func(balancer.DoneInfo), error) {
|
|
||||||
p.mu.Lock()
|
|
||||||
defer p.mu.Unlock()
|
|
||||||
|
|
||||||
// Layer one roundrobin on serverList.
|
|
||||||
s := p.serverList[p.serverListNext]
|
|
||||||
p.serverListNext = (p.serverListNext + 1) % len(p.serverList)
|
|
||||||
|
|
||||||
// If it's a drop, return an error and fail the RPC.
|
|
||||||
if s.DropForRateLimiting {
|
|
||||||
p.stats.dropForRateLimiting()
|
|
||||||
return nil, nil, status.Errorf(codes.Unavailable, "request dropped by grpclb")
|
|
||||||
}
|
|
||||||
if s.DropForLoadBalancing {
|
|
||||||
p.stats.dropForLoadBalancing()
|
|
||||||
return nil, nil, status.Errorf(codes.Unavailable, "request dropped by grpclb")
|
|
||||||
}
|
|
||||||
|
|
||||||
// If not a drop but there's no ready subConns.
|
|
||||||
if len(p.subConns) <= 0 {
|
|
||||||
return nil, nil, balancer.ErrNoSubConnAvailable
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the next ready subConn in the list, also collect rpc stats.
|
|
||||||
sc := p.subConns[p.subConnsNext]
|
|
||||||
p.subConnsNext = (p.subConnsNext + 1) % len(p.subConns)
|
|
||||||
done := func(info balancer.DoneInfo) {
|
|
||||||
if !info.BytesSent {
|
|
||||||
p.stats.failedToSend()
|
|
||||||
} else if info.BytesReceived {
|
|
||||||
p.stats.knownReceived()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sc, done, nil
|
|
||||||
}
|
|
266
vendor/google.golang.org/grpc/grpclb_remote_balancer.go
generated
vendored
266
vendor/google.golang.org/grpc/grpclb_remote_balancer.go
generated
vendored
@ -1,266 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* Copyright 2017 gRPC authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
package grpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"reflect"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
"google.golang.org/grpc/balancer"
|
|
||||||
"google.golang.org/grpc/channelz"
|
|
||||||
|
|
||||||
"google.golang.org/grpc/connectivity"
|
|
||||||
lbpb "google.golang.org/grpc/grpclb/grpc_lb_v1/messages"
|
|
||||||
"google.golang.org/grpc/grpclog"
|
|
||||||
"google.golang.org/grpc/metadata"
|
|
||||||
"google.golang.org/grpc/resolver"
|
|
||||||
)
|
|
||||||
|
|
||||||
// processServerList updates balaner's internal state, create/remove SubConns
|
|
||||||
// and regenerates picker using the received serverList.
|
|
||||||
func (lb *lbBalancer) processServerList(l *lbpb.ServerList) {
|
|
||||||
grpclog.Infof("lbBalancer: processing server list: %+v", l)
|
|
||||||
lb.mu.Lock()
|
|
||||||
defer lb.mu.Unlock()
|
|
||||||
|
|
||||||
// Set serverListReceived to true so fallback will not take effect if it has
|
|
||||||
// not hit timeout.
|
|
||||||
lb.serverListReceived = true
|
|
||||||
|
|
||||||
// If the new server list == old server list, do nothing.
|
|
||||||
if reflect.DeepEqual(lb.fullServerList, l.Servers) {
|
|
||||||
grpclog.Infof("lbBalancer: new serverlist same as the previous one, ignoring")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
lb.fullServerList = l.Servers
|
|
||||||
|
|
||||||
var backendAddrs []resolver.Address
|
|
||||||
for _, s := range l.Servers {
|
|
||||||
if s.DropForLoadBalancing || s.DropForRateLimiting {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
md := metadata.Pairs(lbTokeyKey, s.LoadBalanceToken)
|
|
||||||
ip := net.IP(s.IpAddress)
|
|
||||||
ipStr := ip.String()
|
|
||||||
if ip.To4() == nil {
|
|
||||||
// Add square brackets to ipv6 addresses, otherwise net.Dial() and
|
|
||||||
// net.SplitHostPort() will return too many colons error.
|
|
||||||
ipStr = fmt.Sprintf("[%s]", ipStr)
|
|
||||||
}
|
|
||||||
addr := resolver.Address{
|
|
||||||
Addr: fmt.Sprintf("%s:%d", ipStr, s.Port),
|
|
||||||
Metadata: &md,
|
|
||||||
}
|
|
||||||
|
|
||||||
backendAddrs = append(backendAddrs, addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call refreshSubConns to create/remove SubConns.
|
|
||||||
lb.refreshSubConns(backendAddrs)
|
|
||||||
// Regenerate and update picker no matter if there's update on backends (if
|
|
||||||
// any SubConn will be newed/removed). Because since the full serverList was
|
|
||||||
// different, there might be updates in drops or pick weights(different
|
|
||||||
// number of duplicates). We need to update picker with the fulllist.
|
|
||||||
//
|
|
||||||
// Now with cache, even if SubConn was newed/removed, there might be no
|
|
||||||
// state changes.
|
|
||||||
lb.regeneratePicker()
|
|
||||||
lb.cc.UpdateBalancerState(lb.state, lb.picker)
|
|
||||||
}
|
|
||||||
|
|
||||||
// refreshSubConns creates/removes SubConns with backendAddrs. It returns a bool
|
|
||||||
// indicating whether the backendAddrs are different from the cached
|
|
||||||
// backendAddrs (whether any SubConn was newed/removed).
|
|
||||||
// Caller must hold lb.mu.
|
|
||||||
func (lb *lbBalancer) refreshSubConns(backendAddrs []resolver.Address) bool {
|
|
||||||
lb.backendAddrs = nil
|
|
||||||
var backendsUpdated bool
|
|
||||||
// addrsSet is the set converted from backendAddrs, it's used to quick
|
|
||||||
// lookup for an address.
|
|
||||||
addrsSet := make(map[resolver.Address]struct{})
|
|
||||||
// Create new SubConns.
|
|
||||||
for _, addr := range backendAddrs {
|
|
||||||
addrWithoutMD := addr
|
|
||||||
addrWithoutMD.Metadata = nil
|
|
||||||
addrsSet[addrWithoutMD] = struct{}{}
|
|
||||||
lb.backendAddrs = append(lb.backendAddrs, addrWithoutMD)
|
|
||||||
|
|
||||||
if _, ok := lb.subConns[addrWithoutMD]; !ok {
|
|
||||||
backendsUpdated = true
|
|
||||||
|
|
||||||
// Use addrWithMD to create the SubConn.
|
|
||||||
sc, err := lb.cc.NewSubConn([]resolver.Address{addr}, balancer.NewSubConnOptions{})
|
|
||||||
if err != nil {
|
|
||||||
grpclog.Warningf("roundrobinBalancer: failed to create new SubConn: %v", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
lb.subConns[addrWithoutMD] = sc // Use the addr without MD as key for the map.
|
|
||||||
if _, ok := lb.scStates[sc]; !ok {
|
|
||||||
// Only set state of new sc to IDLE. The state could already be
|
|
||||||
// READY for cached SubConns.
|
|
||||||
lb.scStates[sc] = connectivity.Idle
|
|
||||||
}
|
|
||||||
sc.Connect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for a, sc := range lb.subConns {
|
|
||||||
// a was removed by resolver.
|
|
||||||
if _, ok := addrsSet[a]; !ok {
|
|
||||||
backendsUpdated = true
|
|
||||||
|
|
||||||
lb.cc.RemoveSubConn(sc)
|
|
||||||
delete(lb.subConns, a)
|
|
||||||
// Keep the state of this sc in b.scStates until sc's state becomes Shutdown.
|
|
||||||
// The entry will be deleted in HandleSubConnStateChange.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return backendsUpdated
|
|
||||||
}
|
|
||||||
|
|
||||||
func (lb *lbBalancer) readServerList(s *balanceLoadClientStream) error {
|
|
||||||
for {
|
|
||||||
reply, err := s.Recv()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("grpclb: failed to recv server list: %v", err)
|
|
||||||
}
|
|
||||||
if serverList := reply.GetServerList(); serverList != nil {
|
|
||||||
lb.processServerList(serverList)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (lb *lbBalancer) sendLoadReport(s *balanceLoadClientStream, interval time.Duration) {
|
|
||||||
ticker := time.NewTicker(interval)
|
|
||||||
defer ticker.Stop()
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-ticker.C:
|
|
||||||
case <-s.Context().Done():
|
|
||||||
return
|
|
||||||
}
|
|
||||||
stats := lb.clientStats.toClientStats()
|
|
||||||
t := time.Now()
|
|
||||||
stats.Timestamp = &lbpb.Timestamp{
|
|
||||||
Seconds: t.Unix(),
|
|
||||||
Nanos: int32(t.Nanosecond()),
|
|
||||||
}
|
|
||||||
if err := s.Send(&lbpb.LoadBalanceRequest{
|
|
||||||
LoadBalanceRequestType: &lbpb.LoadBalanceRequest_ClientStats{
|
|
||||||
ClientStats: stats,
|
|
||||||
},
|
|
||||||
}); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (lb *lbBalancer) callRemoteBalancer() error {
|
|
||||||
lbClient := &loadBalancerClient{cc: lb.ccRemoteLB}
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
|
||||||
defer cancel()
|
|
||||||
stream, err := lbClient.BalanceLoad(ctx, FailFast(false))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("grpclb: failed to perform RPC to the remote balancer %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// grpclb handshake on the stream.
|
|
||||||
initReq := &lbpb.LoadBalanceRequest{
|
|
||||||
LoadBalanceRequestType: &lbpb.LoadBalanceRequest_InitialRequest{
|
|
||||||
InitialRequest: &lbpb.InitialLoadBalanceRequest{
|
|
||||||
Name: lb.target,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
if err := stream.Send(initReq); err != nil {
|
|
||||||
return fmt.Errorf("grpclb: failed to send init request: %v", err)
|
|
||||||
}
|
|
||||||
reply, err := stream.Recv()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("grpclb: failed to recv init response: %v", err)
|
|
||||||
}
|
|
||||||
initResp := reply.GetInitialResponse()
|
|
||||||
if initResp == nil {
|
|
||||||
return fmt.Errorf("grpclb: reply from remote balancer did not include initial response")
|
|
||||||
}
|
|
||||||
if initResp.LoadBalancerDelegate != "" {
|
|
||||||
return fmt.Errorf("grpclb: Delegation is not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
if d := convertDuration(initResp.ClientStatsReportInterval); d > 0 {
|
|
||||||
lb.sendLoadReport(stream, d)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
return lb.readServerList(stream)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (lb *lbBalancer) watchRemoteBalancer() {
|
|
||||||
for {
|
|
||||||
err := lb.callRemoteBalancer()
|
|
||||||
select {
|
|
||||||
case <-lb.doneCh:
|
|
||||||
return
|
|
||||||
default:
|
|
||||||
if err != nil {
|
|
||||||
grpclog.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (lb *lbBalancer) dialRemoteLB(remoteLBName string) {
|
|
||||||
var dopts []DialOption
|
|
||||||
if creds := lb.opt.DialCreds; creds != nil {
|
|
||||||
if err := creds.OverrideServerName(remoteLBName); err == nil {
|
|
||||||
dopts = append(dopts, WithTransportCredentials(creds))
|
|
||||||
} else {
|
|
||||||
grpclog.Warningf("grpclb: failed to override the server name in the credentials: %v, using Insecure", err)
|
|
||||||
dopts = append(dopts, WithInsecure())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dopts = append(dopts, WithInsecure())
|
|
||||||
}
|
|
||||||
if lb.opt.Dialer != nil {
|
|
||||||
// WithDialer takes a different type of function, so we instead use a
|
|
||||||
// special DialOption here.
|
|
||||||
dopts = append(dopts, withContextDialer(lb.opt.Dialer))
|
|
||||||
}
|
|
||||||
// Explicitly set pickfirst as the balancer.
|
|
||||||
dopts = append(dopts, WithBalancerName(PickFirstBalancerName))
|
|
||||||
dopts = append(dopts, withResolverBuilder(lb.manualResolver))
|
|
||||||
if channelz.IsOn() {
|
|
||||||
dopts = append(dopts, WithChannelzParentID(lb.opt.ChannelzParentID))
|
|
||||||
}
|
|
||||||
|
|
||||||
// DialContext using manualResolver.Scheme, which is a random scheme generated
|
|
||||||
// when init grpclb. The target name is not important.
|
|
||||||
cc, err := DialContext(context.Background(), "grpclb:///grpclb.server", dopts...)
|
|
||||||
if err != nil {
|
|
||||||
grpclog.Fatalf("failed to dial: %v", err)
|
|
||||||
}
|
|
||||||
lb.ccRemoteLB = cc
|
|
||||||
go lb.watchRemoteBalancer()
|
|
||||||
}
|
|
214
vendor/google.golang.org/grpc/grpclb_util.go
generated
vendored
214
vendor/google.golang.org/grpc/grpclb_util.go
generated
vendored
@ -1,214 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* Copyright 2016 gRPC authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
package grpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"google.golang.org/grpc/balancer"
|
|
||||||
"google.golang.org/grpc/connectivity"
|
|
||||||
"google.golang.org/grpc/resolver"
|
|
||||||
)
|
|
||||||
|
|
||||||
// The parent ClientConn should re-resolve when grpclb loses connection to the
|
|
||||||
// remote balancer. When the ClientConn inside grpclb gets a TransientFailure,
|
|
||||||
// it calls lbManualResolver.ResolveNow(), which calls parent ClientConn's
|
|
||||||
// ResolveNow, and eventually results in re-resolve happening in parent
|
|
||||||
// ClientConn's resolver (DNS for example).
|
|
||||||
//
|
|
||||||
// parent
|
|
||||||
// ClientConn
|
|
||||||
// +-----------------------------------------------------------------+
|
|
||||||
// | parent +---------------------------------+ |
|
|
||||||
// | DNS ClientConn | grpclb | |
|
|
||||||
// | resolver balancerWrapper | | |
|
|
||||||
// | + + | grpclb grpclb | |
|
|
||||||
// | | | | ManualResolver ClientConn | |
|
|
||||||
// | | | | + + | |
|
|
||||||
// | | | | | | Transient | |
|
|
||||||
// | | | | | | Failure | |
|
|
||||||
// | | | | | <--------- | | |
|
|
||||||
// | | | <--------------- | ResolveNow | | |
|
|
||||||
// | | <--------- | ResolveNow | | | | |
|
|
||||||
// | | ResolveNow | | | | | |
|
|
||||||
// | | | | | | | |
|
|
||||||
// | + + | + + | |
|
|
||||||
// | +---------------------------------+ |
|
|
||||||
// +-----------------------------------------------------------------+
|
|
||||||
|
|
||||||
// lbManualResolver is used by the ClientConn inside grpclb. It's a manual
|
|
||||||
// resolver with a special ResolveNow() function.
|
|
||||||
//
|
|
||||||
// When ResolveNow() is called, it calls ResolveNow() on the parent ClientConn,
|
|
||||||
// so when grpclb client lose contact with remote balancers, the parent
|
|
||||||
// ClientConn's resolver will re-resolve.
|
|
||||||
type lbManualResolver struct {
|
|
||||||
scheme string
|
|
||||||
ccr resolver.ClientConn
|
|
||||||
|
|
||||||
ccb balancer.ClientConn
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *lbManualResolver) Build(_ resolver.Target, cc resolver.ClientConn, _ resolver.BuildOption) (resolver.Resolver, error) {
|
|
||||||
r.ccr = cc
|
|
||||||
return r, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *lbManualResolver) Scheme() string {
|
|
||||||
return r.scheme
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResolveNow calls resolveNow on the parent ClientConn.
|
|
||||||
func (r *lbManualResolver) ResolveNow(o resolver.ResolveNowOption) {
|
|
||||||
r.ccb.ResolveNow(o)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close is a noop for Resolver.
|
|
||||||
func (*lbManualResolver) Close() {}
|
|
||||||
|
|
||||||
// NewAddress calls cc.NewAddress.
|
|
||||||
func (r *lbManualResolver) NewAddress(addrs []resolver.Address) {
|
|
||||||
r.ccr.NewAddress(addrs)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewServiceConfig calls cc.NewServiceConfig.
|
|
||||||
func (r *lbManualResolver) NewServiceConfig(sc string) {
|
|
||||||
r.ccr.NewServiceConfig(sc)
|
|
||||||
}
|
|
||||||
|
|
||||||
const subConnCacheTime = time.Second * 10
|
|
||||||
|
|
||||||
// lbCacheClientConn is a wrapper balancer.ClientConn with a SubConn cache.
|
|
||||||
// SubConns will be kept in cache for subConnCacheTime before being removed.
|
|
||||||
//
|
|
||||||
// Its new and remove methods are updated to do cache first.
|
|
||||||
type lbCacheClientConn struct {
|
|
||||||
cc balancer.ClientConn
|
|
||||||
timeout time.Duration
|
|
||||||
|
|
||||||
mu sync.Mutex
|
|
||||||
// subConnCache only keeps subConns that are being deleted.
|
|
||||||
subConnCache map[resolver.Address]*subConnCacheEntry
|
|
||||||
subConnToAddr map[balancer.SubConn]resolver.Address
|
|
||||||
}
|
|
||||||
|
|
||||||
type subConnCacheEntry struct {
|
|
||||||
sc balancer.SubConn
|
|
||||||
|
|
||||||
cancel func()
|
|
||||||
abortDeleting bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func newLBCacheClientConn(cc balancer.ClientConn) *lbCacheClientConn {
|
|
||||||
return &lbCacheClientConn{
|
|
||||||
cc: cc,
|
|
||||||
timeout: subConnCacheTime,
|
|
||||||
subConnCache: make(map[resolver.Address]*subConnCacheEntry),
|
|
||||||
subConnToAddr: make(map[balancer.SubConn]resolver.Address),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ccc *lbCacheClientConn) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) {
|
|
||||||
if len(addrs) != 1 {
|
|
||||||
return nil, fmt.Errorf("grpclb calling NewSubConn with addrs of length %v", len(addrs))
|
|
||||||
}
|
|
||||||
addrWithoutMD := addrs[0]
|
|
||||||
addrWithoutMD.Metadata = nil
|
|
||||||
|
|
||||||
ccc.mu.Lock()
|
|
||||||
defer ccc.mu.Unlock()
|
|
||||||
if entry, ok := ccc.subConnCache[addrWithoutMD]; ok {
|
|
||||||
// If entry is in subConnCache, the SubConn was being deleted.
|
|
||||||
// cancel function will never be nil.
|
|
||||||
entry.cancel()
|
|
||||||
delete(ccc.subConnCache, addrWithoutMD)
|
|
||||||
return entry.sc, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
scNew, err := ccc.cc.NewSubConn(addrs, opts)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ccc.subConnToAddr[scNew] = addrWithoutMD
|
|
||||||
return scNew, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ccc *lbCacheClientConn) RemoveSubConn(sc balancer.SubConn) {
|
|
||||||
ccc.mu.Lock()
|
|
||||||
defer ccc.mu.Unlock()
|
|
||||||
addr, ok := ccc.subConnToAddr[sc]
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if entry, ok := ccc.subConnCache[addr]; ok {
|
|
||||||
if entry.sc != sc {
|
|
||||||
// This could happen if NewSubConn was called multiple times for the
|
|
||||||
// same address, and those SubConns are all removed. We remove sc
|
|
||||||
// immediately here.
|
|
||||||
delete(ccc.subConnToAddr, sc)
|
|
||||||
ccc.cc.RemoveSubConn(sc)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
entry := &subConnCacheEntry{
|
|
||||||
sc: sc,
|
|
||||||
}
|
|
||||||
ccc.subConnCache[addr] = entry
|
|
||||||
|
|
||||||
timer := time.AfterFunc(ccc.timeout, func() {
|
|
||||||
ccc.mu.Lock()
|
|
||||||
if entry.abortDeleting {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ccc.cc.RemoveSubConn(sc)
|
|
||||||
delete(ccc.subConnToAddr, sc)
|
|
||||||
delete(ccc.subConnCache, addr)
|
|
||||||
ccc.mu.Unlock()
|
|
||||||
})
|
|
||||||
entry.cancel = func() {
|
|
||||||
if !timer.Stop() {
|
|
||||||
// If stop was not successful, the timer has fired (this can only
|
|
||||||
// happen in a race). But the deleting function is blocked on ccc.mu
|
|
||||||
// because the mutex was held by the caller of this function.
|
|
||||||
//
|
|
||||||
// Set abortDeleting to true to abort the deleting function. When
|
|
||||||
// the lock is released, the deleting function will acquire the
|
|
||||||
// lock, check the value of abortDeleting and return.
|
|
||||||
entry.abortDeleting = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ccc *lbCacheClientConn) UpdateBalancerState(s connectivity.State, p balancer.Picker) {
|
|
||||||
ccc.cc.UpdateBalancerState(s, p)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ccc *lbCacheClientConn) close() {
|
|
||||||
ccc.mu.Lock()
|
|
||||||
// Only cancel all existing timers. There's no need to remove SubConns.
|
|
||||||
for _, entry := range ccc.subConnCache {
|
|
||||||
entry.cancel()
|
|
||||||
}
|
|
||||||
ccc.mu.Unlock()
|
|
||||||
}
|
|
6
vendor/google.golang.org/grpc/install_gae.sh
generated
vendored
Executable file
6
vendor/google.golang.org/grpc/install_gae.sh
generated
vendored
Executable file
@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
TMP=$(mktemp -d /tmp/sdk.XXX) \
|
||||||
|
&& curl -o $TMP.zip "https://storage.googleapis.com/appengine-sdks/featured/go_appengine_sdk_linux_amd64-1.9.64.zip" \
|
||||||
|
&& unzip -q $TMP.zip -d $TMP \
|
||||||
|
&& export PATH="$PATH:$TMP/go_appengine"
|
78
vendor/google.golang.org/grpc/internal/backoff/backoff.go
generated
vendored
Normal file
78
vendor/google.golang.org/grpc/internal/backoff/backoff.go
generated
vendored
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2017 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Package backoff implement the backoff strategy for gRPC.
|
||||||
|
//
|
||||||
|
// This is kept in internal until the gRPC project decides whether or not to
|
||||||
|
// allow alternative backoff strategies.
|
||||||
|
package backoff
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"google.golang.org/grpc/internal/grpcrand"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Strategy defines the methodology for backing off after a grpc connection
|
||||||
|
// failure.
|
||||||
|
//
|
||||||
|
type Strategy interface {
|
||||||
|
// Backoff returns the amount of time to wait before the next retry given
|
||||||
|
// the number of consecutive failures.
|
||||||
|
Backoff(retries int) time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// baseDelay is the amount of time to wait before retrying after the first
|
||||||
|
// failure.
|
||||||
|
baseDelay = 1.0 * time.Second
|
||||||
|
// factor is applied to the backoff after each retry.
|
||||||
|
factor = 1.6
|
||||||
|
// jitter provides a range to randomize backoff delays.
|
||||||
|
jitter = 0.2
|
||||||
|
)
|
||||||
|
|
||||||
|
// Exponential implements exponential backoff algorithm as defined in
|
||||||
|
// https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md.
|
||||||
|
type Exponential struct {
|
||||||
|
// MaxDelay is the upper bound of backoff delay.
|
||||||
|
MaxDelay time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
// Backoff returns the amount of time to wait before the next retry given the
|
||||||
|
// number of retries.
|
||||||
|
func (bc Exponential) Backoff(retries int) time.Duration {
|
||||||
|
if retries == 0 {
|
||||||
|
return baseDelay
|
||||||
|
}
|
||||||
|
backoff, max := float64(baseDelay), float64(bc.MaxDelay)
|
||||||
|
for backoff < max && retries > 0 {
|
||||||
|
backoff *= factor
|
||||||
|
retries--
|
||||||
|
}
|
||||||
|
if backoff > max {
|
||||||
|
backoff = max
|
||||||
|
}
|
||||||
|
// Randomize backoff delays so that if a cluster of requests start at
|
||||||
|
// the same time, they won't operate in lockstep.
|
||||||
|
backoff *= 1 + jitter*(grpcrand.Float64()*2-1)
|
||||||
|
if backoff < 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return time.Duration(backoff)
|
||||||
|
}
|
56
vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go
generated
vendored
Normal file
56
vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2018 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Package grpcrand implements math/rand functions in a concurrent-safe way
|
||||||
|
// with a global random source, independent of math/rand's global source.
|
||||||
|
package grpcrand
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/rand"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
r = rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
|
mu sync.Mutex
|
||||||
|
)
|
||||||
|
|
||||||
|
// Int63n implements rand.Int63n on the grpcrand global source.
|
||||||
|
func Int63n(n int64) int64 {
|
||||||
|
mu.Lock()
|
||||||
|
res := r.Int63n(n)
|
||||||
|
mu.Unlock()
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// Intn implements rand.Intn on the grpcrand global source.
|
||||||
|
func Intn(n int) int {
|
||||||
|
mu.Lock()
|
||||||
|
res := r.Intn(n)
|
||||||
|
mu.Unlock()
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// Float64 implements rand.Float64 on the grpcrand global source.
|
||||||
|
func Float64() float64 {
|
||||||
|
mu.Lock()
|
||||||
|
res := r.Float64()
|
||||||
|
mu.Unlock()
|
||||||
|
return res
|
||||||
|
}
|
25
vendor/google.golang.org/grpc/internal/internal.go
generated
vendored
25
vendor/google.golang.org/grpc/internal/internal.go
generated
vendored
@ -15,13 +15,22 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Package internal contains gRPC-internal code for testing, to avoid polluting
|
// Package internal contains gRPC-internal code, to avoid polluting
|
||||||
// the godoc of the top-level grpc package.
|
// the godoc of the top-level grpc package. It must not import any grpc
|
||||||
|
// symbols to avoid circular dependencies.
|
||||||
package internal
|
package internal
|
||||||
|
|
||||||
// TestingUseHandlerImpl enables the http.Handler-based server implementation.
|
var (
|
||||||
// It must be called before Serve and requires TLS credentials.
|
|
||||||
//
|
// TestingUseHandlerImpl enables the http.Handler-based server implementation.
|
||||||
// The provided grpcServer must be of type *grpc.Server. It is untyped
|
// It must be called before Serve and requires TLS credentials.
|
||||||
// for circular dependency reasons.
|
//
|
||||||
var TestingUseHandlerImpl func(grpcServer interface{})
|
// The provided grpcServer must be of type *grpc.Server. It is untyped
|
||||||
|
// for circular dependency reasons.
|
||||||
|
TestingUseHandlerImpl func(grpcServer interface{})
|
||||||
|
|
||||||
|
// WithContextDialer is exported by clientconn.go
|
||||||
|
WithContextDialer interface{} // func(context.Context, string) (net.Conn, error) grpc.DialOption
|
||||||
|
// WithResolverBuilder is exported by clientconn.go
|
||||||
|
WithResolverBuilder interface{} // func (resolver.Builder) grpc.DialOption
|
||||||
|
)
|
||||||
|
27
vendor/google.golang.org/grpc/newstream.go
generated
vendored
Normal file
27
vendor/google.golang.org/grpc/newstream.go
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// +build !js !wasm
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2018 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package grpc
|
||||||
|
|
||||||
|
import "golang.org/x/net/context"
|
||||||
|
|
||||||
|
func (cc *ClientConn) newStream(ctx context.Context, desc *StreamDesc, method string, opts ...CallOption) (ClientStream, error) {
|
||||||
|
return cc.makeStream(ctx, desc, method, opts...)
|
||||||
|
}
|
34
vendor/google.golang.org/grpc/newstream_js.go
generated
vendored
Normal file
34
vendor/google.golang.org/grpc/newstream_js.go
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// +build js,wasm
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2018 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package grpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (cc *ClientConn) newStream(ctx context.Context, desc *StreamDesc, method string, opts ...CallOption) (ClientStream, error) {
|
||||||
|
if desc.ClientStreams {
|
||||||
|
return nil, status.Error(codes.Unimplemented, "client-side and bi-directional streaming is not yet supported by gRPC-web")
|
||||||
|
}
|
||||||
|
return cc.makeStream(ctx, desc, method, opts...)
|
||||||
|
}
|
27
vendor/google.golang.org/grpc/parse.go
generated
vendored
Normal file
27
vendor/google.golang.org/grpc/parse.go
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// +build !js !wasm
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2018 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package grpc
|
||||||
|
|
||||||
|
import "google.golang.org/grpc/transport"
|
||||||
|
|
||||||
|
func parseMsg(p *parser, s *transport.Stream, maxReceiveMessageSize int, pf payloadFormat, d []byte) ([]byte, error) {
|
||||||
|
return d, nil
|
||||||
|
}
|
79
vendor/google.golang.org/grpc/parse_js.go
generated
vendored
Normal file
79
vendor/google.golang.org/grpc/parse_js.go
generated
vendored
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
// +build js,wasm
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2018 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package grpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
|
"google.golang.org/grpc/transport"
|
||||||
|
)
|
||||||
|
|
||||||
|
func parseMsg(p *parser, s *transport.Stream, maxReceiveMessageSize int, pf payloadFormat, d []byte) ([]byte, error) {
|
||||||
|
if pf == trailer || pf == compressedTrailer {
|
||||||
|
trailers, err := readTrailers(bytes.NewReader(d), len(d))
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "grpc: failed to parse returned trailers: %v", err)
|
||||||
|
}
|
||||||
|
// Holy layer violation :(
|
||||||
|
// This is necessary because the gRPC-Web trailers are part of the response body. See
|
||||||
|
// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md#protocol-differences-vs-grpc-over-http2
|
||||||
|
err = s.SetTrailers(trailers)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "grpc: failed to set trailers on stream: %v", err)
|
||||||
|
}
|
||||||
|
// Sanity check that parser is done. This should return io.EOF
|
||||||
|
_, _, err = p.recvMsg(maxReceiveMessageSize)
|
||||||
|
if err == io.EOF {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return nil, status.Errorf(codes.Internal, "grpc: unexpected error reading last message from stream: %v", err)
|
||||||
|
}
|
||||||
|
return d, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// readTrailers consumes the rest of the reader and parses the
|
||||||
|
// contents as "\r\n"-separated trailers, in accordance with
|
||||||
|
// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md#protocol-differences-vs-grpc-over-http2
|
||||||
|
func readTrailers(in io.Reader, bufSize int) (http.Header, error) {
|
||||||
|
s := bufio.NewScanner(in)
|
||||||
|
buf := make([]byte, bufSize)
|
||||||
|
s.Buffer(buf, len(buf))
|
||||||
|
// Uses http.Header instead of metadata.MD as .Add method
|
||||||
|
// normalizes trailer keys.
|
||||||
|
trailers := http.Header{}
|
||||||
|
for s.Scan() {
|
||||||
|
v := s.Text()
|
||||||
|
kv := strings.SplitN(v, ": ", 2)
|
||||||
|
if len(kv) != 2 {
|
||||||
|
return nil, errors.New("malformed trailer: " + v)
|
||||||
|
}
|
||||||
|
trailers.Add(kv[0], kv[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
return trailers, s.Err()
|
||||||
|
}
|
21
vendor/google.golang.org/grpc/picker_wrapper.go
generated
vendored
21
vendor/google.golang.org/grpc/picker_wrapper.go
generated
vendored
@ -25,9 +25,9 @@ import (
|
|||||||
|
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
"google.golang.org/grpc/balancer"
|
"google.golang.org/grpc/balancer"
|
||||||
"google.golang.org/grpc/channelz"
|
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/grpclog"
|
"google.golang.org/grpc/grpclog"
|
||||||
|
"google.golang.org/grpc/internal/channelz"
|
||||||
"google.golang.org/grpc/metadata"
|
"google.golang.org/grpc/metadata"
|
||||||
"google.golang.org/grpc/resolver"
|
"google.golang.org/grpc/resolver"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
@ -233,6 +233,8 @@ func (bp *pickerWrapper) close() {
|
|||||||
close(bp.blockingCh)
|
close(bp.blockingCh)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const stickinessKeyCountLimit = 1000
|
||||||
|
|
||||||
type stickyStoreEntry struct {
|
type stickyStoreEntry struct {
|
||||||
acw *acBalancerWrapper
|
acw *acBalancerWrapper
|
||||||
addr resolver.Address
|
addr resolver.Address
|
||||||
@ -243,12 +245,12 @@ type stickyStore struct {
|
|||||||
// curMDKey is check before every get/put to avoid races. The operation will
|
// curMDKey is check before every get/put to avoid races. The operation will
|
||||||
// abort immediately when the given mdKey is different from the curMDKey.
|
// abort immediately when the given mdKey is different from the curMDKey.
|
||||||
curMDKey string
|
curMDKey string
|
||||||
store map[string]*stickyStoreEntry
|
store *linkedMap
|
||||||
}
|
}
|
||||||
|
|
||||||
func newStickyStore() *stickyStore {
|
func newStickyStore() *stickyStore {
|
||||||
return &stickyStore{
|
return &stickyStore{
|
||||||
store: make(map[string]*stickyStoreEntry),
|
store: newLinkedMap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,7 +258,7 @@ func newStickyStore() *stickyStore {
|
|||||||
func (ss *stickyStore) reset(newMDKey string) {
|
func (ss *stickyStore) reset(newMDKey string) {
|
||||||
ss.mu.Lock()
|
ss.mu.Lock()
|
||||||
ss.curMDKey = newMDKey
|
ss.curMDKey = newMDKey
|
||||||
ss.store = make(map[string]*stickyStoreEntry)
|
ss.store.clear()
|
||||||
ss.mu.Unlock()
|
ss.mu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,9 +271,12 @@ func (ss *stickyStore) put(mdKey, stickyKey string, acw *acBalancerWrapper) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
// TODO(stickiness): limit the total number of entries.
|
// TODO(stickiness): limit the total number of entries.
|
||||||
ss.store[stickyKey] = &stickyStoreEntry{
|
ss.store.put(stickyKey, &stickyStoreEntry{
|
||||||
acw: acw,
|
acw: acw,
|
||||||
addr: acw.getAddrConn().getCurAddr(),
|
addr: acw.getAddrConn().getCurAddr(),
|
||||||
|
})
|
||||||
|
if ss.store.len() > stickinessKeyCountLimit {
|
||||||
|
ss.store.removeOldest()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,18 +288,18 @@ func (ss *stickyStore) get(mdKey, stickyKey string) (transport.ClientTransport,
|
|||||||
if mdKey != ss.curMDKey {
|
if mdKey != ss.curMDKey {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
entry, ok := ss.store[stickyKey]
|
entry, ok := ss.store.get(stickyKey)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
ac := entry.acw.getAddrConn()
|
ac := entry.acw.getAddrConn()
|
||||||
if ac.getCurAddr() != entry.addr {
|
if ac.getCurAddr() != entry.addr {
|
||||||
delete(ss.store, stickyKey)
|
ss.store.remove(stickyKey)
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
t, ok := ac.getReadyTransport()
|
t, ok := ac.getReadyTransport()
|
||||||
if !ok {
|
if !ok {
|
||||||
delete(ss.store, stickyKey)
|
ss.store.remove(stickyKey)
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
return t, true
|
return t, true
|
||||||
|
25
vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go
generated
vendored
25
vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go
generated
vendored
@ -24,7 +24,6 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -34,6 +33,7 @@ import (
|
|||||||
|
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
"google.golang.org/grpc/grpclog"
|
"google.golang.org/grpc/grpclog"
|
||||||
|
"google.golang.org/grpc/internal/grpcrand"
|
||||||
"google.golang.org/grpc/resolver"
|
"google.golang.org/grpc/resolver"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -51,8 +51,13 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errMissingAddr = errors.New("missing address")
|
errMissingAddr = errors.New("dns resolver: missing address")
|
||||||
randomGen = rand.New(rand.NewSource(time.Now().UnixNano()))
|
|
||||||
|
// Addresses ending with a colon that is supposed to be the separator
|
||||||
|
// between host and port is not allowed. E.g. "::" is a valid address as
|
||||||
|
// it is an IPv6 address (host only) and "[::]:" is invalid as it ends with
|
||||||
|
// a colon as the host and port separator
|
||||||
|
errEndsWithColon = errors.New("dns resolver: missing port after port-separator colon")
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewBuilder creates a dnsBuilder which is used to factory DNS resolvers.
|
// NewBuilder creates a dnsBuilder which is used to factory DNS resolvers.
|
||||||
@ -67,6 +72,9 @@ type dnsBuilder struct {
|
|||||||
|
|
||||||
// Build creates and starts a DNS resolver that watches the name resolution of the target.
|
// Build creates and starts a DNS resolver that watches the name resolution of the target.
|
||||||
func (b *dnsBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOption) (resolver.Resolver, error) {
|
func (b *dnsBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOption) (resolver.Resolver, error) {
|
||||||
|
if target.Authority != "" {
|
||||||
|
return nil, fmt.Errorf("Default DNS resolver does not support custom DNS server")
|
||||||
|
}
|
||||||
host, port, err := parseTarget(target.Endpoint)
|
host, port, err := parseTarget(target.Endpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -295,7 +303,6 @@ func formatIP(addr string) (addrIP string, ok bool) {
|
|||||||
// target: "ipv4-host:80" returns host: "ipv4-host", port: "80"
|
// target: "ipv4-host:80" returns host: "ipv4-host", port: "80"
|
||||||
// target: "[ipv6-host]" returns host: "ipv6-host", port: "443"
|
// target: "[ipv6-host]" returns host: "ipv6-host", port: "443"
|
||||||
// target: ":80" returns host: "localhost", port: "80"
|
// target: ":80" returns host: "localhost", port: "80"
|
||||||
// target: ":" returns host: "localhost", port: "443"
|
|
||||||
func parseTarget(target string) (host, port string, err error) {
|
func parseTarget(target string) (host, port string, err error) {
|
||||||
if target == "" {
|
if target == "" {
|
||||||
return "", "", errMissingAddr
|
return "", "", errMissingAddr
|
||||||
@ -305,15 +312,15 @@ func parseTarget(target string) (host, port string, err error) {
|
|||||||
return target, defaultPort, nil
|
return target, defaultPort, nil
|
||||||
}
|
}
|
||||||
if host, port, err = net.SplitHostPort(target); err == nil {
|
if host, port, err = net.SplitHostPort(target); err == nil {
|
||||||
|
if port == "" {
|
||||||
|
// If the port field is empty (target ends with colon), e.g. "[::1]:", this is an error.
|
||||||
|
return "", "", errEndsWithColon
|
||||||
|
}
|
||||||
// target has port, i.e ipv4-host:port, [ipv6-host]:port, host-name:port
|
// target has port, i.e ipv4-host:port, [ipv6-host]:port, host-name:port
|
||||||
if host == "" {
|
if host == "" {
|
||||||
// Keep consistent with net.Dial(): If the host is empty, as in ":80", the local system is assumed.
|
// Keep consistent with net.Dial(): If the host is empty, as in ":80", the local system is assumed.
|
||||||
host = "localhost"
|
host = "localhost"
|
||||||
}
|
}
|
||||||
if port == "" {
|
|
||||||
// If the port field is empty(target ends with colon), e.g. "[::1]:", defaultPort is used.
|
|
||||||
port = defaultPort
|
|
||||||
}
|
|
||||||
return host, port, nil
|
return host, port, nil
|
||||||
}
|
}
|
||||||
if host, port, err = net.SplitHostPort(target + ":" + defaultPort); err == nil {
|
if host, port, err = net.SplitHostPort(target + ":" + defaultPort); err == nil {
|
||||||
@ -346,7 +353,7 @@ func chosenByPercentage(a *int) bool {
|
|||||||
if a == nil {
|
if a == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return randomGen.Intn(100)+1 <= *a
|
return grpcrand.Intn(100)+1 <= *a
|
||||||
}
|
}
|
||||||
|
|
||||||
func canaryingSC(js string) string {
|
func canaryingSC(js string) string {
|
||||||
|
6
vendor/google.golang.org/grpc/resolver_conn_wrapper.go
generated
vendored
6
vendor/google.golang.org/grpc/resolver_conn_wrapper.go
generated
vendored
@ -65,8 +65,8 @@ func parseTarget(target string) (ret resolver.Target) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// newCCResolverWrapper parses cc.target for scheme and gets the resolver
|
// newCCResolverWrapper parses cc.target for scheme and gets the resolver
|
||||||
// builder for this scheme. It then builds the resolver and starts the
|
// builder for this scheme and builds the resolver. The monitoring goroutine
|
||||||
// monitoring goroutine for it.
|
// for it is not started yet and can be created by calling start().
|
||||||
//
|
//
|
||||||
// If withResolverBuilder dial option is set, the specified resolver will be
|
// If withResolverBuilder dial option is set, the specified resolver will be
|
||||||
// used instead.
|
// used instead.
|
||||||
@ -148,7 +148,7 @@ func (ccr *ccResolverWrapper) NewAddress(addrs []resolver.Address) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewServiceConfig is called by the resolver implemenetion to send service
|
// NewServiceConfig is called by the resolver implemenetion to send service
|
||||||
// configs to gPRC.
|
// configs to gRPC.
|
||||||
func (ccr *ccResolverWrapper) NewServiceConfig(sc string) {
|
func (ccr *ccResolverWrapper) NewServiceConfig(sc string) {
|
||||||
select {
|
select {
|
||||||
case <-ccr.scCh:
|
case <-ccr.scCh:
|
||||||
|
140
vendor/google.golang.org/grpc/rpc_util.go
generated
vendored
140
vendor/google.golang.org/grpc/rpc_util.go
generated
vendored
@ -419,8 +419,12 @@ func (o CustomCodecCallOption) after(c *callInfo) {}
|
|||||||
type payloadFormat uint8
|
type payloadFormat uint8
|
||||||
|
|
||||||
const (
|
const (
|
||||||
compressionNone payloadFormat = iota // no compression
|
compressionNone payloadFormat = 0 // no compression
|
||||||
compressionMade
|
compressionMade payloadFormat = 1 // compressed
|
||||||
|
// Defined for gRPC-Web
|
||||||
|
// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md#protocol-differences-vs-grpc-over-http2
|
||||||
|
trailer payloadFormat = 1 << 7
|
||||||
|
compressedTrailer payloadFormat = (1 << 7) | 1
|
||||||
)
|
)
|
||||||
|
|
||||||
// parser reads complete gRPC messages from the underlying reader.
|
// parser reads complete gRPC messages from the underlying reader.
|
||||||
@ -477,71 +481,88 @@ func (p *parser) recvMsg(maxReceiveMessageSize int) (pf payloadFormat, msg []byt
|
|||||||
return pf, msg, nil
|
return pf, msg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// encode serializes msg and returns a buffer of message header and a buffer of msg.
|
// encode serializes msg and returns a buffer containing the message, or an
|
||||||
// If msg is nil, it generates the message header and an empty msg buffer.
|
// error if it is too large to be transmitted by grpc. If msg is nil, it
|
||||||
// TODO(ddyihai): eliminate extra Compressor parameter.
|
// generates an empty message.
|
||||||
func encode(c baseCodec, msg interface{}, cp Compressor, outPayload *stats.OutPayload, compressor encoding.Compressor) ([]byte, []byte, error) {
|
func encode(c baseCodec, msg interface{}) ([]byte, error) {
|
||||||
var (
|
if msg == nil { // NOTE: typed nils will not be caught by this check
|
||||||
b []byte
|
return nil, nil
|
||||||
cbuf *bytes.Buffer
|
}
|
||||||
)
|
b, err := c.Marshal(msg)
|
||||||
const (
|
if err != nil {
|
||||||
payloadLen = 1
|
return nil, status.Errorf(codes.Internal, "grpc: error while marshaling: %v", err.Error())
|
||||||
sizeLen = 4
|
|
||||||
)
|
|
||||||
if msg != nil {
|
|
||||||
var err error
|
|
||||||
b, err = c.Marshal(msg)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, status.Errorf(codes.Internal, "grpc: error while marshaling: %v", err.Error())
|
|
||||||
}
|
|
||||||
if outPayload != nil {
|
|
||||||
outPayload.Payload = msg
|
|
||||||
// TODO truncate large payload.
|
|
||||||
outPayload.Data = b
|
|
||||||
outPayload.Length = len(b)
|
|
||||||
}
|
|
||||||
if compressor != nil || cp != nil {
|
|
||||||
cbuf = new(bytes.Buffer)
|
|
||||||
// Has compressor, check Compressor is set by UseCompressor first.
|
|
||||||
if compressor != nil {
|
|
||||||
z, _ := compressor.Compress(cbuf)
|
|
||||||
if _, err := z.Write(b); err != nil {
|
|
||||||
return nil, nil, status.Errorf(codes.Internal, "grpc: error while compressing: %v", err.Error())
|
|
||||||
}
|
|
||||||
z.Close()
|
|
||||||
} else {
|
|
||||||
// If Compressor is not set by UseCompressor, use default Compressor
|
|
||||||
if err := cp.Do(cbuf, b); err != nil {
|
|
||||||
return nil, nil, status.Errorf(codes.Internal, "grpc: error while compressing: %v", err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
b = cbuf.Bytes()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if uint(len(b)) > math.MaxUint32 {
|
if uint(len(b)) > math.MaxUint32 {
|
||||||
return nil, nil, status.Errorf(codes.ResourceExhausted, "grpc: message too large (%d bytes)", len(b))
|
return nil, status.Errorf(codes.ResourceExhausted, "grpc: message too large (%d bytes)", len(b))
|
||||||
}
|
}
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
bufHeader := make([]byte, payloadLen+sizeLen)
|
// compress returns the input bytes compressed by compressor or cp. If both
|
||||||
if compressor != nil || cp != nil {
|
// compressors are nil, returns nil.
|
||||||
bufHeader[0] = byte(compressionMade)
|
//
|
||||||
|
// TODO(dfawley): eliminate cp parameter by wrapping Compressor in an encoding.Compressor.
|
||||||
|
func compress(in []byte, cp Compressor, compressor encoding.Compressor) ([]byte, error) {
|
||||||
|
if compressor == nil && cp == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
wrapErr := func(err error) error {
|
||||||
|
return status.Errorf(codes.Internal, "grpc: error while compressing: %v", err.Error())
|
||||||
|
}
|
||||||
|
cbuf := &bytes.Buffer{}
|
||||||
|
if compressor != nil {
|
||||||
|
z, _ := compressor.Compress(cbuf)
|
||||||
|
if _, err := z.Write(in); err != nil {
|
||||||
|
return nil, wrapErr(err)
|
||||||
|
}
|
||||||
|
if err := z.Close(); err != nil {
|
||||||
|
return nil, wrapErr(err)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
bufHeader[0] = byte(compressionNone)
|
if err := cp.Do(cbuf, in); err != nil {
|
||||||
|
return nil, wrapErr(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cbuf.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
payloadLen = 1
|
||||||
|
sizeLen = 4
|
||||||
|
headerLen = payloadLen + sizeLen
|
||||||
|
)
|
||||||
|
|
||||||
|
// msgHeader returns a 5-byte header for the message being transmitted and the
|
||||||
|
// payload, which is compData if non-nil or data otherwise.
|
||||||
|
func msgHeader(data, compData []byte) (hdr []byte, payload []byte) {
|
||||||
|
hdr = make([]byte, headerLen)
|
||||||
|
if compData != nil {
|
||||||
|
hdr[0] = byte(compressionMade)
|
||||||
|
data = compData
|
||||||
|
} else {
|
||||||
|
hdr[0] = byte(compressionNone)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write length of b into buf
|
// Write length of payload into buf
|
||||||
binary.BigEndian.PutUint32(bufHeader[payloadLen:], uint32(len(b)))
|
binary.BigEndian.PutUint32(hdr[payloadLen:], uint32(len(data)))
|
||||||
if outPayload != nil {
|
return hdr, data
|
||||||
outPayload.WireLength = payloadLen + sizeLen + len(b)
|
}
|
||||||
|
|
||||||
|
func outPayload(client bool, msg interface{}, data, payload []byte, t time.Time) *stats.OutPayload {
|
||||||
|
return &stats.OutPayload{
|
||||||
|
Client: client,
|
||||||
|
Payload: msg,
|
||||||
|
Data: data,
|
||||||
|
Length: len(data),
|
||||||
|
WireLength: len(payload) + headerLen,
|
||||||
|
SentTime: t,
|
||||||
}
|
}
|
||||||
return bufHeader, b, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkRecvPayload(pf payloadFormat, recvCompress string, haveCompressor bool) *status.Status {
|
func checkRecvPayload(pf payloadFormat, recvCompress string, haveCompressor bool) *status.Status {
|
||||||
switch pf {
|
switch pf {
|
||||||
case compressionNone:
|
case compressionNone, trailer:
|
||||||
case compressionMade:
|
case compressionMade, compressedTrailer:
|
||||||
if recvCompress == "" || recvCompress == encoding.Identity {
|
if recvCompress == "" || recvCompress == encoding.Identity {
|
||||||
return status.New(codes.Internal, "grpc: compressed flag set with identity or empty encoding")
|
return status.New(codes.Internal, "grpc: compressed flag set with identity or empty encoding")
|
||||||
}
|
}
|
||||||
@ -570,7 +591,7 @@ func recv(p *parser, c baseCodec, s *transport.Stream, dc Decompressor, m interf
|
|||||||
return st.Err()
|
return st.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
if pf == compressionMade {
|
if pf == compressionMade || pf == compressedTrailer {
|
||||||
// To match legacy behavior, if the decompressor is set by WithDecompressor or RPCDecompressor,
|
// To match legacy behavior, if the decompressor is set by WithDecompressor or RPCDecompressor,
|
||||||
// use this decompressor as the default.
|
// use this decompressor as the default.
|
||||||
if dc != nil {
|
if dc != nil {
|
||||||
@ -594,6 +615,10 @@ func recv(p *parser, c baseCodec, s *transport.Stream, dc Decompressor, m interf
|
|||||||
// implementation.
|
// implementation.
|
||||||
return status.Errorf(codes.ResourceExhausted, "grpc: received message larger than max (%d vs. %d)", len(d), maxReceiveMessageSize)
|
return status.Errorf(codes.ResourceExhausted, "grpc: received message larger than max (%d vs. %d)", len(d), maxReceiveMessageSize)
|
||||||
}
|
}
|
||||||
|
d, err = parseMsg(p, s, maxReceiveMessageSize, pf, d)
|
||||||
|
if err != nil {
|
||||||
|
return err // already a status error (or io.EOF)
|
||||||
|
}
|
||||||
if err := c.Unmarshal(d, m); err != nil {
|
if err := c.Unmarshal(d, m); err != nil {
|
||||||
return status.Errorf(codes.Internal, "grpc: failed to unmarshal the received message %v", err)
|
return status.Errorf(codes.Internal, "grpc: failed to unmarshal the received message %v", err)
|
||||||
}
|
}
|
||||||
@ -721,7 +746,4 @@ const (
|
|||||||
SupportPackageIsVersion5 = true
|
SupportPackageIsVersion5 = true
|
||||||
)
|
)
|
||||||
|
|
||||||
// Version is the current grpc version.
|
|
||||||
const Version = "1.12.0"
|
|
||||||
|
|
||||||
const grpcUA = "grpc-go/" + Version
|
const grpcUA = "grpc-go/" + Version
|
||||||
|
28
vendor/google.golang.org/grpc/server.go
generated
vendored
28
vendor/google.golang.org/grpc/server.go
generated
vendored
@ -38,13 +38,13 @@ import (
|
|||||||
"golang.org/x/net/http2"
|
"golang.org/x/net/http2"
|
||||||
"golang.org/x/net/trace"
|
"golang.org/x/net/trace"
|
||||||
|
|
||||||
"google.golang.org/grpc/channelz"
|
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
"google.golang.org/grpc/encoding"
|
"google.golang.org/grpc/encoding"
|
||||||
"google.golang.org/grpc/encoding/proto"
|
"google.golang.org/grpc/encoding/proto"
|
||||||
"google.golang.org/grpc/grpclog"
|
"google.golang.org/grpc/grpclog"
|
||||||
"google.golang.org/grpc/internal"
|
"google.golang.org/grpc/internal"
|
||||||
|
"google.golang.org/grpc/internal/channelz"
|
||||||
"google.golang.org/grpc/keepalive"
|
"google.golang.org/grpc/keepalive"
|
||||||
"google.golang.org/grpc/metadata"
|
"google.golang.org/grpc/metadata"
|
||||||
"google.golang.org/grpc/stats"
|
"google.golang.org/grpc/stats"
|
||||||
@ -827,24 +827,24 @@ func (s *Server) incrCallsFailed() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) sendResponse(t transport.ServerTransport, stream *transport.Stream, msg interface{}, cp Compressor, opts *transport.Options, comp encoding.Compressor) error {
|
func (s *Server) sendResponse(t transport.ServerTransport, stream *transport.Stream, msg interface{}, cp Compressor, opts *transport.Options, comp encoding.Compressor) error {
|
||||||
var (
|
data, err := encode(s.getCodec(stream.ContentSubtype()), msg)
|
||||||
outPayload *stats.OutPayload
|
|
||||||
)
|
|
||||||
if s.opts.statsHandler != nil {
|
|
||||||
outPayload = &stats.OutPayload{}
|
|
||||||
}
|
|
||||||
hdr, data, err := encode(s.getCodec(stream.ContentSubtype()), msg, cp, outPayload, comp)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
grpclog.Errorln("grpc: server failed to encode response: ", err)
|
grpclog.Errorln("grpc: server failed to encode response: ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(data) > s.opts.maxSendMessageSize {
|
compData, err := compress(data, cp, comp)
|
||||||
return status.Errorf(codes.ResourceExhausted, "grpc: trying to send message larger than max (%d vs. %d)", len(data), s.opts.maxSendMessageSize)
|
if err != nil {
|
||||||
|
grpclog.Errorln("grpc: server failed to compress response: ", err)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
err = t.Write(stream, hdr, data, opts)
|
hdr, payload := msgHeader(data, compData)
|
||||||
if err == nil && outPayload != nil {
|
// TODO(dfawley): should we be checking len(data) instead?
|
||||||
outPayload.SentTime = time.Now()
|
if len(payload) > s.opts.maxSendMessageSize {
|
||||||
s.opts.statsHandler.HandleRPC(stream.Context(), outPayload)
|
return status.Errorf(codes.ResourceExhausted, "grpc: trying to send message larger than max (%d vs. %d)", len(payload), s.opts.maxSendMessageSize)
|
||||||
|
}
|
||||||
|
err = t.Write(stream, hdr, payload, opts)
|
||||||
|
if err == nil && s.opts.statsHandler != nil {
|
||||||
|
s.opts.statsHandler.HandleRPC(stream.Context(), outPayload(false, msg, data, payload, time.Now()))
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
42
vendor/google.golang.org/grpc/status/go16.go
generated
vendored
Normal file
42
vendor/google.golang.org/grpc/status/go16.go
generated
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// +build go1.6,!go1.7
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2018 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package status
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FromContextError converts a context error into a Status. It returns a
|
||||||
|
// Status with codes.OK if err is nil, or a Status with codes.Unknown if err is
|
||||||
|
// non-nil and not a context error.
|
||||||
|
func FromContextError(err error) *Status {
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return New(codes.OK, "")
|
||||||
|
case context.DeadlineExceeded:
|
||||||
|
return New(codes.DeadlineExceeded, err.Error())
|
||||||
|
case context.Canceled:
|
||||||
|
return New(codes.Canceled, err.Error())
|
||||||
|
default:
|
||||||
|
return New(codes.Unknown, err.Error())
|
||||||
|
}
|
||||||
|
}
|
44
vendor/google.golang.org/grpc/status/go17.go
generated
vendored
Normal file
44
vendor/google.golang.org/grpc/status/go17.go
generated
vendored
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// +build go1.7
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2018 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package status
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
netctx "golang.org/x/net/context"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FromContextError converts a context error into a Status. It returns a
|
||||||
|
// Status with codes.OK if err is nil, or a Status with codes.Unknown if err is
|
||||||
|
// non-nil and not a context error.
|
||||||
|
func FromContextError(err error) *Status {
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return New(codes.OK, "")
|
||||||
|
case context.DeadlineExceeded, netctx.DeadlineExceeded:
|
||||||
|
return New(codes.DeadlineExceeded, err.Error())
|
||||||
|
case context.Canceled, netctx.Canceled:
|
||||||
|
return New(codes.Canceled, err.Error())
|
||||||
|
default:
|
||||||
|
return New(codes.Unknown, err.Error())
|
||||||
|
}
|
||||||
|
}
|
97
vendor/google.golang.org/grpc/stickiness_linkedmap.go
generated
vendored
Normal file
97
vendor/google.golang.org/grpc/stickiness_linkedmap.go
generated
vendored
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2018 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package grpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"container/list"
|
||||||
|
)
|
||||||
|
|
||||||
|
type linkedMapKVPair struct {
|
||||||
|
key string
|
||||||
|
value *stickyStoreEntry
|
||||||
|
}
|
||||||
|
|
||||||
|
// linkedMap is an implementation of a map that supports removing the oldest
|
||||||
|
// entry.
|
||||||
|
//
|
||||||
|
// linkedMap is NOT thread safe.
|
||||||
|
//
|
||||||
|
// It's for use of stickiness only!
|
||||||
|
type linkedMap struct {
|
||||||
|
m map[string]*list.Element
|
||||||
|
l *list.List // Head of the list is the oldest element.
|
||||||
|
}
|
||||||
|
|
||||||
|
// newLinkedMap returns a new LinkedMap.
|
||||||
|
func newLinkedMap() *linkedMap {
|
||||||
|
return &linkedMap{
|
||||||
|
m: make(map[string]*list.Element),
|
||||||
|
l: list.New(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// put adds entry (key, value) to the map. Existing key will be overridden.
|
||||||
|
func (m *linkedMap) put(key string, value *stickyStoreEntry) {
|
||||||
|
if oldE, ok := m.m[key]; ok {
|
||||||
|
// Remove existing entry.
|
||||||
|
m.l.Remove(oldE)
|
||||||
|
}
|
||||||
|
e := m.l.PushBack(&linkedMapKVPair{key: key, value: value})
|
||||||
|
m.m[key] = e
|
||||||
|
}
|
||||||
|
|
||||||
|
// get returns the value of the given key.
|
||||||
|
func (m *linkedMap) get(key string) (*stickyStoreEntry, bool) {
|
||||||
|
e, ok := m.m[key]
|
||||||
|
if !ok {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
m.l.MoveToBack(e)
|
||||||
|
return e.Value.(*linkedMapKVPair).value, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove removes key from the map, and returns the value. The map is not
|
||||||
|
// modified if key is not in the map.
|
||||||
|
func (m *linkedMap) remove(key string) (*stickyStoreEntry, bool) {
|
||||||
|
e, ok := m.m[key]
|
||||||
|
if !ok {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
delete(m.m, key)
|
||||||
|
m.l.Remove(e)
|
||||||
|
return e.Value.(*linkedMapKVPair).value, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// len returns the len of the map.
|
||||||
|
func (m *linkedMap) len() int {
|
||||||
|
return len(m.m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear removes all elements from the map.
|
||||||
|
func (m *linkedMap) clear() {
|
||||||
|
m.m = make(map[string]*list.Element)
|
||||||
|
m.l = list.New()
|
||||||
|
}
|
||||||
|
|
||||||
|
// removeOldest removes the oldest key from the map.
|
||||||
|
func (m *linkedMap) removeOldest() {
|
||||||
|
e := m.l.Front()
|
||||||
|
m.l.Remove(e)
|
||||||
|
delete(m.m, e.Value.(*linkedMapKVPair).key)
|
||||||
|
}
|
74
vendor/google.golang.org/grpc/stream.go
generated
vendored
74
vendor/google.golang.org/grpc/stream.go
generated
vendored
@ -27,9 +27,9 @@ import (
|
|||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
"golang.org/x/net/trace"
|
"golang.org/x/net/trace"
|
||||||
"google.golang.org/grpc/balancer"
|
"google.golang.org/grpc/balancer"
|
||||||
"google.golang.org/grpc/channelz"
|
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/encoding"
|
"google.golang.org/grpc/encoding"
|
||||||
|
"google.golang.org/grpc/internal/channelz"
|
||||||
"google.golang.org/grpc/metadata"
|
"google.golang.org/grpc/metadata"
|
||||||
"google.golang.org/grpc/stats"
|
"google.golang.org/grpc/stats"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
@ -101,8 +101,26 @@ type ClientStream interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewStream creates a new Stream for the client side. This is typically
|
// NewStream creates a new Stream for the client side. This is typically
|
||||||
// called by generated code.
|
// called by generated code. ctx is used for the lifetime of the stream.
|
||||||
|
//
|
||||||
|
// To ensure resources are not leaked due to the stream returned, one of the following
|
||||||
|
// actions must be performed:
|
||||||
|
//
|
||||||
|
// 1. Call Close on the ClientConn.
|
||||||
|
// 2. Cancel the context provided.
|
||||||
|
// 3. Call RecvMsg until a non-nil error is returned. A protobuf-generated
|
||||||
|
// client-streaming RPC, for instance, might use the helper function
|
||||||
|
// CloseAndRecv (note that CloseSend does not Recv, therefore is not
|
||||||
|
// guaranteed to release all resources).
|
||||||
|
// 4. Receive a non-nil, non-io.EOF error from Header or SendMsg.
|
||||||
|
//
|
||||||
|
// If none of the above happen, a goroutine and a context will be leaked, and grpc
|
||||||
|
// will not call the optionally-configured stats handler with a stats.End message.
|
||||||
func (cc *ClientConn) NewStream(ctx context.Context, desc *StreamDesc, method string, opts ...CallOption) (ClientStream, error) {
|
func (cc *ClientConn) NewStream(ctx context.Context, desc *StreamDesc, method string, opts ...CallOption) (ClientStream, error) {
|
||||||
|
return cc.newStream(ctx, desc, method, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cc *ClientConn) makeStream(ctx context.Context, desc *StreamDesc, method string, opts ...CallOption) (ClientStream, error) {
|
||||||
// allow interceptor to see all applicable call options, which means those
|
// allow interceptor to see all applicable call options, which means those
|
||||||
// configured as defaults from dial option as well as per-call options
|
// configured as defaults from dial option as well as per-call options
|
||||||
opts = combine(cc.dopts.callOptions, opts)
|
opts = combine(cc.dopts.callOptions, opts)
|
||||||
@ -113,8 +131,7 @@ func (cc *ClientConn) NewStream(ctx context.Context, desc *StreamDesc, method st
|
|||||||
return newClientStream(ctx, desc, cc, method, opts...)
|
return newClientStream(ctx, desc, cc, method, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewClientStream creates a new Stream for the client side. This is typically
|
// NewClientStream is a wrapper for ClientConn.NewStream.
|
||||||
// called by generated code.
|
|
||||||
//
|
//
|
||||||
// DEPRECATED: Use ClientConn.NewStream instead.
|
// DEPRECATED: Use ClientConn.NewStream instead.
|
||||||
func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (ClientStream, error) {
|
func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (ClientStream, error) {
|
||||||
@ -466,27 +483,27 @@ func (a *csAttempt) sendMsg(m interface{}) (err error) {
|
|||||||
}
|
}
|
||||||
a.mu.Unlock()
|
a.mu.Unlock()
|
||||||
}
|
}
|
||||||
var outPayload *stats.OutPayload
|
data, err := encode(cs.codec, m)
|
||||||
if a.statsHandler != nil {
|
|
||||||
outPayload = &stats.OutPayload{
|
|
||||||
Client: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hdr, data, err := encode(cs.codec, m, cs.cp, outPayload, cs.comp)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(data) > *cs.c.maxSendMessageSize {
|
compData, err := compress(data, cs.cp, cs.comp)
|
||||||
return status.Errorf(codes.ResourceExhausted, "trying to send message larger than max (%d vs. %d)", len(data), *cs.c.maxSendMessageSize)
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
hdr, payload := msgHeader(data, compData)
|
||||||
|
// TODO(dfawley): should we be checking len(data) instead?
|
||||||
|
if len(payload) > *cs.c.maxSendMessageSize {
|
||||||
|
return status.Errorf(codes.ResourceExhausted, "trying to send message larger than max (%d vs. %d)", len(payload), *cs.c.maxSendMessageSize)
|
||||||
|
}
|
||||||
|
|
||||||
if !cs.desc.ClientStreams {
|
if !cs.desc.ClientStreams {
|
||||||
cs.sentLast = true
|
cs.sentLast = true
|
||||||
}
|
}
|
||||||
err = a.t.Write(a.s, hdr, data, &transport.Options{Last: !cs.desc.ClientStreams})
|
err = a.t.Write(a.s, hdr, payload, &transport.Options{Last: !cs.desc.ClientStreams})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if outPayload != nil {
|
if a.statsHandler != nil {
|
||||||
outPayload.SentTime = time.Now()
|
a.statsHandler.HandleRPC(a.ctx, outPayload(true, m, data, payload, time.Now()))
|
||||||
a.statsHandler.HandleRPC(a.ctx, outPayload)
|
|
||||||
}
|
}
|
||||||
if channelz.IsOn() {
|
if channelz.IsOn() {
|
||||||
a.t.IncrMsgSent()
|
a.t.IncrMsgSent()
|
||||||
@ -696,23 +713,24 @@ func (ss *serverStream) SendMsg(m interface{}) (err error) {
|
|||||||
ss.t.IncrMsgSent()
|
ss.t.IncrMsgSent()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
var outPayload *stats.OutPayload
|
data, err := encode(ss.codec, m)
|
||||||
if ss.statsHandler != nil {
|
|
||||||
outPayload = &stats.OutPayload{}
|
|
||||||
}
|
|
||||||
hdr, data, err := encode(ss.codec, m, ss.cp, outPayload, ss.comp)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(data) > ss.maxSendMessageSize {
|
compData, err := compress(data, ss.cp, ss.comp)
|
||||||
return status.Errorf(codes.ResourceExhausted, "trying to send message larger than max (%d vs. %d)", len(data), ss.maxSendMessageSize)
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
if err := ss.t.Write(ss.s, hdr, data, &transport.Options{Last: false}); err != nil {
|
hdr, payload := msgHeader(data, compData)
|
||||||
|
// TODO(dfawley): should we be checking len(data) instead?
|
||||||
|
if len(payload) > ss.maxSendMessageSize {
|
||||||
|
return status.Errorf(codes.ResourceExhausted, "trying to send message larger than max (%d vs. %d)", len(payload), ss.maxSendMessageSize)
|
||||||
|
}
|
||||||
|
if err := ss.t.Write(ss.s, hdr, payload, &transport.Options{Last: false}); err != nil {
|
||||||
return toRPCErr(err)
|
return toRPCErr(err)
|
||||||
}
|
}
|
||||||
if outPayload != nil {
|
if ss.statsHandler != nil {
|
||||||
outPayload.SentTime = time.Now()
|
ss.statsHandler.HandleRPC(ss.s.Context(), outPayload(false, m, data, payload, time.Now()))
|
||||||
ss.statsHandler.HandleRPC(ss.s.Context(), outPayload)
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
1039
vendor/google.golang.org/grpc/transport/client_transport.go
generated
vendored
Normal file
1039
vendor/google.golang.org/grpc/transport/client_transport.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
266
vendor/google.golang.org/grpc/transport/client_transport_js.go
generated
vendored
Normal file
266
vendor/google.golang.org/grpc/transport/client_transport_js.go
generated
vendored
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
// +build js,wasm
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2018 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package transport
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"sync/atomic"
|
||||||
|
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
"golang.org/x/net/http2/hpack"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
"google.golang.org/grpc/peer"
|
||||||
|
"google.golang.org/grpc/stats"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
|
)
|
||||||
|
|
||||||
|
// newHTTP2Client constructs a connected ClientTransport to addr based on HTTP2
|
||||||
|
// and starts to receive messages on it. Non-nil error returns if construction
|
||||||
|
// fails.
|
||||||
|
func newHTTP2Client(connectCtx, ctx context.Context, addr TargetInfo, opts ConnectOptions, onSuccess func()) (_ ClientTransport, err error) {
|
||||||
|
ctx, cancel := context.WithCancel(ctx)
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
cancel()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
t := &http2Client{
|
||||||
|
ctx: ctx,
|
||||||
|
cancel: cancel,
|
||||||
|
md: addr.Metadata,
|
||||||
|
readerDone: make(chan struct{}),
|
||||||
|
writerDone: make(chan struct{}),
|
||||||
|
goAway: make(chan struct{}),
|
||||||
|
activeStreams: make(map[uint32]*Stream),
|
||||||
|
creds: opts.PerRPCCredentials,
|
||||||
|
statsHandler: opts.StatsHandler,
|
||||||
|
initialWindowSize: initialWindowSize,
|
||||||
|
nextID: 1,
|
||||||
|
maxConcurrentStreams: defaultMaxStreamsClient,
|
||||||
|
streamQuota: defaultMaxStreamsClient,
|
||||||
|
streamsQuotaAvailable: make(chan struct{}, 1),
|
||||||
|
}
|
||||||
|
if opts.StatsHandler != nil {
|
||||||
|
t.ctx = opts.StatsHandler.TagConn(t.ctx, &stats.ConnTagInfo{
|
||||||
|
RemoteAddr: t.remoteAddr,
|
||||||
|
LocalAddr: t.localAddr,
|
||||||
|
})
|
||||||
|
connBegin := &stats.ConnBegin{
|
||||||
|
Client: true,
|
||||||
|
}
|
||||||
|
t.statsHandler.HandleConn(t.ctx, connBegin)
|
||||||
|
}
|
||||||
|
defer onSuccess()
|
||||||
|
return t, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, error) {
|
||||||
|
ctx = peer.NewContext(ctx, t.getPeer())
|
||||||
|
ctx, cancel := context.WithCancel(ctx)
|
||||||
|
s := &Stream{
|
||||||
|
ctx: ctx,
|
||||||
|
cancel: cancel,
|
||||||
|
headerChan: make(chan struct{}),
|
||||||
|
respChan: make(chan struct{}),
|
||||||
|
done: make(chan struct{}),
|
||||||
|
}
|
||||||
|
|
||||||
|
endpoint := callHdr.Method
|
||||||
|
if callHdr.Host != "" {
|
||||||
|
endpoint = callHdr.Host + "/" + endpoint
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest(
|
||||||
|
"POST",
|
||||||
|
endpoint,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
s.req = req.WithContext(s.ctx)
|
||||||
|
|
||||||
|
headerFields, err := t.createHeaderFields(s.ctx, callHdr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, hf := range headerFields {
|
||||||
|
// Filter out HTTP2 metadata headers
|
||||||
|
if strings.HasPrefix(hf.Name, ":") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Don't add the user-agent header
|
||||||
|
if strings.ToLower(hf.Name) == "user-agent" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Add(hf.Name, hf.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set gRPC-Web specific headers
|
||||||
|
// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md#protocol-differences-vs-grpc-over-http2
|
||||||
|
req.Header.Add("X-Grpc-Web", "1")
|
||||||
|
req.Header.Add("X-User-Agent", "grpc-web-javascript/0.1")
|
||||||
|
|
||||||
|
if t.statsHandler != nil {
|
||||||
|
outHeader := &stats.OutHeader{
|
||||||
|
Client: true,
|
||||||
|
FullMethod: callHdr.Method,
|
||||||
|
RemoteAddr: t.remoteAddr,
|
||||||
|
LocalAddr: t.localAddr,
|
||||||
|
Compression: callHdr.SendCompress,
|
||||||
|
}
|
||||||
|
t.statsHandler.HandleRPC(s.ctx, outHeader)
|
||||||
|
}
|
||||||
|
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *http2Client) Write(s *Stream, hdr []byte, data []byte, opts *Options) error {
|
||||||
|
if atomic.SwapUint32(&s.requestSent, 1) == 1 {
|
||||||
|
return status.Error(codes.Unimplemented, "multiple Write's are not supported.")
|
||||||
|
}
|
||||||
|
|
||||||
|
s.req.Body = ioutil.NopCloser(bytes.NewBuffer(append(hdr, data...)))
|
||||||
|
|
||||||
|
resp, err := http.DefaultClient.Do(s.req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = t.operateHeaders(s, resp.Header, &s.req.URL.Path, &resp.StatusCode)
|
||||||
|
if err != nil {
|
||||||
|
resp.Body.Close()
|
||||||
|
s.writeErr = err
|
||||||
|
close(s.respChan)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
s.body = resp.Body
|
||||||
|
close(s.respChan)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *http2Client) Close() error {
|
||||||
|
if t.statsHandler != nil {
|
||||||
|
connEnd := &stats.ConnEnd{
|
||||||
|
Client: true,
|
||||||
|
}
|
||||||
|
t.statsHandler.HandleConn(t.ctx, connEnd)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (t *http2Client) GracefulClose() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (t *http2Client) GetGoAwayReason() GoAwayReason {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
func (t *http2Client) CloseStream(stream *Stream, err error) {
|
||||||
|
if stream.cancel != nil {
|
||||||
|
stream.cancel()
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
case <-stream.respChan:
|
||||||
|
if stream.body != nil {
|
||||||
|
stream.body.Close()
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (t *http2Client) IncrMsgSent() {}
|
||||||
|
func (t *http2Client) IncrMsgRecv() {}
|
||||||
|
|
||||||
|
func (d *decodeState) decodeResponseHeader(headers http.Header, path *string, status *int) error {
|
||||||
|
for key, values := range headers {
|
||||||
|
for _, value := range values {
|
||||||
|
if err := d.processHeaderField(hpack.HeaderField{Name: strings.ToLower(key), Value: value}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if path != nil {
|
||||||
|
if err := d.processHeaderField(hpack.HeaderField{Name: ":path", Value: *path}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if status != nil {
|
||||||
|
if err := d.processHeaderField(hpack.HeaderField{Name: ":status", Value: strconv.Itoa(*status)}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return d.validate()
|
||||||
|
}
|
||||||
|
|
||||||
|
// operateHeaders takes action on the decoded headers.
|
||||||
|
func (t *http2Client) operateHeaders(s *Stream, headers http.Header, path *string, status *int) error {
|
||||||
|
atomic.StoreUint32(&s.bytesReceived, 1)
|
||||||
|
var state decodeState
|
||||||
|
if err := state.decodeResponseHeader(headers, path, status); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if t != nil && t.statsHandler != nil {
|
||||||
|
inHeader := &stats.InHeader{
|
||||||
|
Client: true,
|
||||||
|
}
|
||||||
|
t.statsHandler.HandleRPC(s.ctx, inHeader)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
// If headers haven't been received yet.
|
||||||
|
if atomic.SwapUint32(&s.headerDone, 1) == 0 {
|
||||||
|
// These values can be set without any synchronization because
|
||||||
|
// stream goroutine will read it only after seeing a closed
|
||||||
|
// headerChan which we'll close after setting this.
|
||||||
|
s.recvCompress = state.encoding
|
||||||
|
if len(state.mdata) > 0 {
|
||||||
|
s.header = state.mdata
|
||||||
|
}
|
||||||
|
close(s.headerChan)
|
||||||
|
}
|
||||||
|
if state.rawStatusCode == nil || state.rawStatusMsg == "" || state.statusGen == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.swapState(streamDone) == streamDone {
|
||||||
|
// If it was already done, return.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
s.status = state.status()
|
||||||
|
if len(state.mdata) > 0 {
|
||||||
|
s.trailer = state.mdata
|
||||||
|
}
|
||||||
|
close(s.done)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTrailers sets the trailers on the stream. This is unique to the WASM client
|
||||||
|
// as trailers are not read by the stream but by the user of the stream.
|
||||||
|
func (s *Stream) SetTrailers(trailers http.Header) error {
|
||||||
|
return (*http2Client)(nil).operateHeaders(s, trailers, nil, nil)
|
||||||
|
}
|
64
vendor/google.golang.org/grpc/transport/content_type.go
generated
vendored
Normal file
64
vendor/google.golang.org/grpc/transport/content_type.go
generated
vendored
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// +build !js !wasm
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2018 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package transport
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
const (
|
||||||
|
// baseContentType is the base content-type for gRPC. This is a valid
|
||||||
|
// content-type on it's own, but can also include a content-subtype such as
|
||||||
|
// "proto" as a suffix after "+" or ";". See
|
||||||
|
// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests
|
||||||
|
// for more details.
|
||||||
|
baseContentType = "application/grpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
// contentSubtype returns the content-subtype for the given content-type. The
|
||||||
|
// given content-type must be a valid content-type that starts with
|
||||||
|
// "application/grpc". A content-subtype will follow "application/grpc" after a
|
||||||
|
// "+" or ";". See
|
||||||
|
// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests for
|
||||||
|
// more details.
|
||||||
|
//
|
||||||
|
// If contentType is not a valid content-type for gRPC, the boolean
|
||||||
|
// will be false, otherwise true. If content-type == "application/grpc",
|
||||||
|
// "application/grpc+", or "application/grpc;", the boolean will be true,
|
||||||
|
// but no content-subtype will be returned.
|
||||||
|
//
|
||||||
|
// contentType is assumed to be lowercase already.
|
||||||
|
func contentSubtype(contentType string) (string, bool) {
|
||||||
|
if contentType == baseContentType {
|
||||||
|
return "", true
|
||||||
|
}
|
||||||
|
if !strings.HasPrefix(contentType, baseContentType) {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
// guaranteed since != baseContentType and has baseContentType prefix
|
||||||
|
switch contentType[len(baseContentType)] {
|
||||||
|
case '+', ';':
|
||||||
|
// this will return true for "application/grpc+" or "application/grpc;"
|
||||||
|
// which the previous validContentType function tested to be valid, so we
|
||||||
|
// just say that no content-subtype is specified in this case
|
||||||
|
return contentType[len(baseContentType)+1:], true
|
||||||
|
default:
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
}
|
68
vendor/google.golang.org/grpc/transport/content_type_js.go
generated
vendored
Normal file
68
vendor/google.golang.org/grpc/transport/content_type_js.go
generated
vendored
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
// +build js,wasm
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2018 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package transport
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
const (
|
||||||
|
// baseContentType is the base content-type for gRPC-web. This is a valid
|
||||||
|
// content-type on it's own, but can also include a content-subtype such as
|
||||||
|
// "proto" as a suffix after "+" or ";". See
|
||||||
|
// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md#protocol-differences-vs-grpc-over-http2
|
||||||
|
// for more details.
|
||||||
|
baseContentType = "application/grpc-web"
|
||||||
|
)
|
||||||
|
|
||||||
|
// contentSubtype returns the content-subtype for the given content-type. The
|
||||||
|
// given content-type must be a valid content-type that starts with
|
||||||
|
// "application/grpc". A content-subtype will follow "application/grpc" after a
|
||||||
|
// "+" or ";". See
|
||||||
|
// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md#protocol-differences-vs-grpc-over-http2
|
||||||
|
// for more details.
|
||||||
|
//
|
||||||
|
// If contentType is not a valid content-type for gRPC, the boolean
|
||||||
|
// will be false, otherwise true. If content-type == "application/grpc",
|
||||||
|
// "application/grpc+", or "application/grpc;", the boolean will be true,
|
||||||
|
// but no content-subtype will be returned.
|
||||||
|
//
|
||||||
|
// contentType is assumed to be lowercase already.
|
||||||
|
func contentSubtype(contentType string) (string, bool) {
|
||||||
|
switch contentType {
|
||||||
|
// We allow application/octet-stream because this
|
||||||
|
// is the content type returned by the browser
|
||||||
|
// when reading a streaming response from a Fetch API request.
|
||||||
|
case baseContentType, "application/octet-stream":
|
||||||
|
return "", true
|
||||||
|
}
|
||||||
|
if !strings.HasPrefix(contentType, baseContentType) {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
// guaranteed since != baseContentType and has baseContentType prefix
|
||||||
|
switch contentType[len(baseContentType)] {
|
||||||
|
case '+', ';':
|
||||||
|
// this will return true for "application/grpc+" or "application/grpc;"
|
||||||
|
// which the previous validContentType function tested to be valid, so we
|
||||||
|
// just say that no content-subtype is specified in this case
|
||||||
|
return contentType[len(baseContentType)+1:], true
|
||||||
|
default:
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
}
|
101
vendor/google.golang.org/grpc/transport/controlbuf.go
generated
vendored
101
vendor/google.golang.org/grpc/transport/controlbuf.go
generated
vendored
@ -28,6 +28,10 @@ import (
|
|||||||
"golang.org/x/net/http2/hpack"
|
"golang.org/x/net/http2/hpack"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var updateHeaderTblSize = func(e *hpack.Encoder, v uint32) {
|
||||||
|
e.SetMaxDynamicTableSizeLimit(v)
|
||||||
|
}
|
||||||
|
|
||||||
type itemNode struct {
|
type itemNode struct {
|
||||||
it interface{}
|
it interface{}
|
||||||
next *itemNode
|
next *itemNode
|
||||||
@ -80,6 +84,13 @@ func (il *itemList) isEmpty() bool {
|
|||||||
// the control buffer of transport. They represent different aspects of
|
// the control buffer of transport. They represent different aspects of
|
||||||
// control tasks, e.g., flow control, settings, streaming resetting, etc.
|
// control tasks, e.g., flow control, settings, streaming resetting, etc.
|
||||||
|
|
||||||
|
// registerStream is used to register an incoming stream with loopy writer.
|
||||||
|
type registerStream struct {
|
||||||
|
streamID uint32
|
||||||
|
wq *writeQuota
|
||||||
|
}
|
||||||
|
|
||||||
|
// headerFrame is also used to register stream on the client-side.
|
||||||
type headerFrame struct {
|
type headerFrame struct {
|
||||||
streamID uint32
|
streamID uint32
|
||||||
hf []hpack.HeaderField
|
hf []hpack.HeaderField
|
||||||
@ -361,44 +372,47 @@ func newLoopyWriter(s side, fr *framer, cbuf *controlBuffer, bdpEst *bdpEstimato
|
|||||||
const minBatchSize = 1000
|
const minBatchSize = 1000
|
||||||
|
|
||||||
// run should be run in a separate goroutine.
|
// run should be run in a separate goroutine.
|
||||||
func (l *loopyWriter) run() {
|
func (l *loopyWriter) run() (err error) {
|
||||||
var (
|
|
||||||
it interface{}
|
|
||||||
err error
|
|
||||||
isEmpty bool
|
|
||||||
)
|
|
||||||
defer func() {
|
defer func() {
|
||||||
errorf("transport: loopyWriter.run returning. Err: %v", err)
|
if err == ErrConnClosing {
|
||||||
|
// Don't log ErrConnClosing as error since it happens
|
||||||
|
// 1. When the connection is closed by some other known issue.
|
||||||
|
// 2. User closed the connection.
|
||||||
|
// 3. A graceful close of connection.
|
||||||
|
infof("transport: loopyWriter.run returning. %v", err)
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
for {
|
for {
|
||||||
it, err = l.cbuf.get(true)
|
it, err := l.cbuf.get(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
if err = l.handle(it); err != nil {
|
if err = l.handle(it); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
if _, err = l.processData(); err != nil {
|
if _, err = l.processData(); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
gosched := true
|
gosched := true
|
||||||
hasdata:
|
hasdata:
|
||||||
for {
|
for {
|
||||||
it, err = l.cbuf.get(false)
|
it, err := l.cbuf.get(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
if it != nil {
|
if it != nil {
|
||||||
if err = l.handle(it); err != nil {
|
if err = l.handle(it); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
if _, err = l.processData(); err != nil {
|
if _, err = l.processData(); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
continue hasdata
|
continue hasdata
|
||||||
}
|
}
|
||||||
if isEmpty, err = l.processData(); err != nil {
|
isEmpty, err := l.processData()
|
||||||
return
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
if !isEmpty {
|
if !isEmpty {
|
||||||
continue hasdata
|
continue hasdata
|
||||||
@ -450,30 +464,39 @@ func (l *loopyWriter) incomingSettingsHandler(s *incomingSettings) error {
|
|||||||
return l.framer.fr.WriteSettingsAck()
|
return l.framer.fr.WriteSettingsAck()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *loopyWriter) registerStreamHandler(h *registerStream) error {
|
||||||
|
str := &outStream{
|
||||||
|
id: h.streamID,
|
||||||
|
state: empty,
|
||||||
|
itl: &itemList{},
|
||||||
|
wq: h.wq,
|
||||||
|
}
|
||||||
|
l.estdStreams[h.streamID] = str
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (l *loopyWriter) headerHandler(h *headerFrame) error {
|
func (l *loopyWriter) headerHandler(h *headerFrame) error {
|
||||||
if l.side == serverSide {
|
if l.side == serverSide {
|
||||||
if h.endStream { // Case 1.A: Server wants to close stream.
|
str, ok := l.estdStreams[h.streamID]
|
||||||
// Make sure it's not a trailers only response.
|
if !ok {
|
||||||
if str, ok := l.estdStreams[h.streamID]; ok {
|
warningf("transport: loopy doesn't recognize the stream: %d", h.streamID)
|
||||||
if str.state != empty { // either active or waiting on stream quota.
|
return nil
|
||||||
// add it str's list of items.
|
|
||||||
str.itl.enqueue(h)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err := l.writeHeader(h.streamID, h.endStream, h.hf, h.onWrite); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return l.cleanupStreamHandler(h.cleanup)
|
|
||||||
}
|
}
|
||||||
// Case 1.B: Server is responding back with headers.
|
// Case 1.A: Server is responding back with headers.
|
||||||
str := &outStream{
|
if !h.endStream {
|
||||||
state: empty,
|
return l.writeHeader(h.streamID, h.endStream, h.hf, h.onWrite)
|
||||||
itl: &itemList{},
|
|
||||||
wq: h.wq,
|
|
||||||
}
|
}
|
||||||
l.estdStreams[h.streamID] = str
|
// else: Case 1.B: Server wants to close stream.
|
||||||
return l.writeHeader(h.streamID, h.endStream, h.hf, h.onWrite)
|
|
||||||
|
if str.state != empty { // either active or waiting on stream quota.
|
||||||
|
// add it str's list of items.
|
||||||
|
str.itl.enqueue(h)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if err := l.writeHeader(h.streamID, h.endStream, h.hf, h.onWrite); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return l.cleanupStreamHandler(h.cleanup)
|
||||||
}
|
}
|
||||||
// Case 2: Client wants to originate stream.
|
// Case 2: Client wants to originate stream.
|
||||||
str := &outStream{
|
str := &outStream{
|
||||||
@ -632,6 +655,8 @@ func (l *loopyWriter) handle(i interface{}) error {
|
|||||||
return l.outgoingSettingsHandler(i)
|
return l.outgoingSettingsHandler(i)
|
||||||
case *headerFrame:
|
case *headerFrame:
|
||||||
return l.headerHandler(i)
|
return l.headerHandler(i)
|
||||||
|
case *registerStream:
|
||||||
|
return l.registerStreamHandler(i)
|
||||||
case *cleanupStream:
|
case *cleanupStream:
|
||||||
return l.cleanupStreamHandler(i)
|
return l.cleanupStreamHandler(i)
|
||||||
case *incomingGoAway:
|
case *incomingGoAway:
|
||||||
@ -664,6 +689,8 @@ func (l *loopyWriter) applySettings(ss []http2.Setting) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case http2.SettingHeaderTableSize:
|
||||||
|
updateHeaderTblSize(l.hEnc, s.Val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
10
vendor/google.golang.org/grpc/transport/flowcontrol.go
generated
vendored
10
vendor/google.golang.org/grpc/transport/flowcontrol.go
generated
vendored
@ -58,14 +58,20 @@ type writeQuota struct {
|
|||||||
ch chan struct{}
|
ch chan struct{}
|
||||||
// done is triggered in error case.
|
// done is triggered in error case.
|
||||||
done <-chan struct{}
|
done <-chan struct{}
|
||||||
|
// replenish is called by loopyWriter to give quota back to.
|
||||||
|
// It is implemented as a field so that it can be updated
|
||||||
|
// by tests.
|
||||||
|
replenish func(n int)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newWriteQuota(sz int32, done <-chan struct{}) *writeQuota {
|
func newWriteQuota(sz int32, done <-chan struct{}) *writeQuota {
|
||||||
return &writeQuota{
|
w := &writeQuota{
|
||||||
quota: sz,
|
quota: sz,
|
||||||
ch: make(chan struct{}, 1),
|
ch: make(chan struct{}, 1),
|
||||||
done: done,
|
done: done,
|
||||||
}
|
}
|
||||||
|
w.replenish = w.realReplenish
|
||||||
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *writeQuota) get(sz int32) error {
|
func (w *writeQuota) get(sz int32) error {
|
||||||
@ -83,7 +89,7 @@ func (w *writeQuota) get(sz int32) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *writeQuota) replenish(n int) {
|
func (w *writeQuota) realReplenish(n int) {
|
||||||
sz := int32(n)
|
sz := int32(n)
|
||||||
a := atomic.AddInt32(&w.quota, sz)
|
a := atomic.AddInt32(&w.quota, sz)
|
||||||
b := a - sz
|
b := a - sz
|
||||||
|
989
vendor/google.golang.org/grpc/transport/http2_client.go
generated
vendored
989
vendor/google.golang.org/grpc/transport/http2_client.go
generated
vendored
File diff suppressed because it is too large
Load Diff
118
vendor/google.golang.org/grpc/transport/http2_server.go
generated
vendored
118
vendor/google.golang.org/grpc/transport/http2_server.go
generated
vendored
@ -24,7 +24,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
"math/rand"
|
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
@ -36,9 +35,11 @@ import (
|
|||||||
"golang.org/x/net/http2"
|
"golang.org/x/net/http2"
|
||||||
"golang.org/x/net/http2/hpack"
|
"golang.org/x/net/http2/hpack"
|
||||||
|
|
||||||
"google.golang.org/grpc/channelz"
|
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
|
"google.golang.org/grpc/grpclog"
|
||||||
|
"google.golang.org/grpc/internal/channelz"
|
||||||
|
"google.golang.org/grpc/internal/grpcrand"
|
||||||
"google.golang.org/grpc/keepalive"
|
"google.golang.org/grpc/keepalive"
|
||||||
"google.golang.org/grpc/metadata"
|
"google.golang.org/grpc/metadata"
|
||||||
"google.golang.org/grpc/peer"
|
"google.golang.org/grpc/peer"
|
||||||
@ -273,7 +274,9 @@ func newHTTP2Server(conn net.Conn, config *ServerConfig) (_ ServerTransport, err
|
|||||||
go func() {
|
go func() {
|
||||||
t.loopy = newLoopyWriter(serverSide, t.framer, t.controlBuf, t.bdpEst)
|
t.loopy = newLoopyWriter(serverSide, t.framer, t.controlBuf, t.bdpEst)
|
||||||
t.loopy.ssGoAwayHandler = t.outgoingGoAwayHandler
|
t.loopy.ssGoAwayHandler = t.outgoingGoAwayHandler
|
||||||
t.loopy.run()
|
if err := t.loopy.run(); err != nil {
|
||||||
|
errorf("transport: loopyWriter.run returning. Err: %v", err)
|
||||||
|
}
|
||||||
t.conn.Close()
|
t.conn.Close()
|
||||||
close(t.writerDone)
|
close(t.writerDone)
|
||||||
}()
|
}()
|
||||||
@ -413,6 +416,11 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
|
|||||||
t.updateWindow(s, uint32(n))
|
t.updateWindow(s, uint32(n))
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
// Register the stream with loopy.
|
||||||
|
t.controlBuf.put(®isterStream{
|
||||||
|
streamID: s.id,
|
||||||
|
wq: s.wq,
|
||||||
|
})
|
||||||
handle(s)
|
handle(s)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -682,28 +690,7 @@ func (t *http2Server) handleWindowUpdate(f *http2.WindowUpdateFrame) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteHeader sends the header metedata md back to the client.
|
func appendHeaderFieldsFromMD(headerFields []hpack.HeaderField, md metadata.MD) []hpack.HeaderField {
|
||||||
func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error {
|
|
||||||
if s.headerOk || s.getState() == streamDone {
|
|
||||||
return ErrIllegalHeaderWrite
|
|
||||||
}
|
|
||||||
s.headerOk = true
|
|
||||||
if md.Len() > 0 {
|
|
||||||
if s.header.Len() > 0 {
|
|
||||||
s.header = metadata.Join(s.header, md)
|
|
||||||
} else {
|
|
||||||
s.header = md
|
|
||||||
}
|
|
||||||
}
|
|
||||||
md = s.header
|
|
||||||
// TODO(mmukhi): Benchmark if the performance gets better if count the metadata and other header fields
|
|
||||||
// first and create a slice of that exact size.
|
|
||||||
headerFields := make([]hpack.HeaderField, 0, 2) // at least :status, content-type will be there if none else.
|
|
||||||
headerFields = append(headerFields, hpack.HeaderField{Name: ":status", Value: "200"})
|
|
||||||
headerFields = append(headerFields, hpack.HeaderField{Name: "content-type", Value: contentType(s.contentSubtype)})
|
|
||||||
if s.sendCompress != "" {
|
|
||||||
headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-encoding", Value: s.sendCompress})
|
|
||||||
}
|
|
||||||
for k, vv := range md {
|
for k, vv := range md {
|
||||||
if isReservedHeader(k) {
|
if isReservedHeader(k) {
|
||||||
// Clients don't tolerate reading restricted headers after some non restricted ones were sent.
|
// Clients don't tolerate reading restricted headers after some non restricted ones were sent.
|
||||||
@ -713,6 +700,37 @@ func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error {
|
|||||||
headerFields = append(headerFields, hpack.HeaderField{Name: k, Value: encodeMetadataHeader(k, v)})
|
headerFields = append(headerFields, hpack.HeaderField{Name: k, Value: encodeMetadataHeader(k, v)})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return headerFields
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteHeader sends the header metedata md back to the client.
|
||||||
|
func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error {
|
||||||
|
if s.updateHeaderSent() || s.getState() == streamDone {
|
||||||
|
return ErrIllegalHeaderWrite
|
||||||
|
}
|
||||||
|
s.hdrMu.Lock()
|
||||||
|
if md.Len() > 0 {
|
||||||
|
if s.header.Len() > 0 {
|
||||||
|
s.header = metadata.Join(s.header, md)
|
||||||
|
} else {
|
||||||
|
s.header = md
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t.writeHeaderLocked(s)
|
||||||
|
s.hdrMu.Unlock()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *http2Server) writeHeaderLocked(s *Stream) {
|
||||||
|
// TODO(mmukhi): Benchmark if the performance gets better if count the metadata and other header fields
|
||||||
|
// first and create a slice of that exact size.
|
||||||
|
headerFields := make([]hpack.HeaderField, 0, 2) // at least :status, content-type will be there if none else.
|
||||||
|
headerFields = append(headerFields, hpack.HeaderField{Name: ":status", Value: "200"})
|
||||||
|
headerFields = append(headerFields, hpack.HeaderField{Name: "content-type", Value: contentType(s.contentSubtype)})
|
||||||
|
if s.sendCompress != "" {
|
||||||
|
headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-encoding", Value: s.sendCompress})
|
||||||
|
}
|
||||||
|
headerFields = appendHeaderFieldsFromMD(headerFields, s.header)
|
||||||
t.controlBuf.put(&headerFrame{
|
t.controlBuf.put(&headerFrame{
|
||||||
streamID: s.id,
|
streamID: s.id,
|
||||||
hf: headerFields,
|
hf: headerFields,
|
||||||
@ -720,7 +738,6 @@ func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error {
|
|||||||
onWrite: func() {
|
onWrite: func() {
|
||||||
atomic.StoreUint32(&t.resetPingStrikes, 1)
|
atomic.StoreUint32(&t.resetPingStrikes, 1)
|
||||||
},
|
},
|
||||||
wq: s.wq,
|
|
||||||
})
|
})
|
||||||
if t.stats != nil {
|
if t.stats != nil {
|
||||||
// Note: WireLength is not set in outHeader.
|
// Note: WireLength is not set in outHeader.
|
||||||
@ -728,7 +745,6 @@ func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error {
|
|||||||
outHeader := &stats.OutHeader{}
|
outHeader := &stats.OutHeader{}
|
||||||
t.stats.HandleRPC(s.Context(), outHeader)
|
t.stats.HandleRPC(s.Context(), outHeader)
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteStatus sends stream status to the client and terminates the stream.
|
// WriteStatus sends stream status to the client and terminates the stream.
|
||||||
@ -736,21 +752,20 @@ func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error {
|
|||||||
// TODO(zhaoq): Now it indicates the end of entire stream. Revisit if early
|
// TODO(zhaoq): Now it indicates the end of entire stream. Revisit if early
|
||||||
// OK is adopted.
|
// OK is adopted.
|
||||||
func (t *http2Server) WriteStatus(s *Stream, st *status.Status) error {
|
func (t *http2Server) WriteStatus(s *Stream, st *status.Status) error {
|
||||||
if !s.headerOk && s.header.Len() > 0 {
|
if s.getState() == streamDone {
|
||||||
if err := t.WriteHeader(s, nil); err != nil {
|
return nil
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if s.getState() == streamDone {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
s.hdrMu.Lock()
|
||||||
// TODO(mmukhi): Benchmark if the performance gets better if count the metadata and other header fields
|
// TODO(mmukhi): Benchmark if the performance gets better if count the metadata and other header fields
|
||||||
// first and create a slice of that exact size.
|
// first and create a slice of that exact size.
|
||||||
headerFields := make([]hpack.HeaderField, 0, 2) // grpc-status and grpc-message will be there if none else.
|
headerFields := make([]hpack.HeaderField, 0, 2) // grpc-status and grpc-message will be there if none else.
|
||||||
if !s.headerOk {
|
if !s.updateHeaderSent() { // No headers have been sent.
|
||||||
headerFields = append(headerFields, hpack.HeaderField{Name: ":status", Value: "200"})
|
if len(s.header) > 0 { // Send a separate header frame.
|
||||||
headerFields = append(headerFields, hpack.HeaderField{Name: "content-type", Value: contentType(s.contentSubtype)})
|
t.writeHeaderLocked(s)
|
||||||
|
} else { // Send a trailer only response.
|
||||||
|
headerFields = append(headerFields, hpack.HeaderField{Name: ":status", Value: "200"})
|
||||||
|
headerFields = append(headerFields, hpack.HeaderField{Name: "content-type", Value: contentType(s.contentSubtype)})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-status", Value: strconv.Itoa(int(st.Code()))})
|
headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-status", Value: strconv.Itoa(int(st.Code()))})
|
||||||
headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-message", Value: encodeGrpcMessage(st.Message())})
|
headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-message", Value: encodeGrpcMessage(st.Message())})
|
||||||
@ -759,23 +774,15 @@ func (t *http2Server) WriteStatus(s *Stream, st *status.Status) error {
|
|||||||
stBytes, err := proto.Marshal(p)
|
stBytes, err := proto.Marshal(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: return error instead, when callers are able to handle it.
|
// TODO: return error instead, when callers are able to handle it.
|
||||||
panic(err)
|
grpclog.Errorf("transport: failed to marshal rpc status: %v, error: %v", p, err)
|
||||||
|
} else {
|
||||||
|
headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-status-details-bin", Value: encodeBinHeader(stBytes)})
|
||||||
}
|
}
|
||||||
|
|
||||||
headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-status-details-bin", Value: encodeBinHeader(stBytes)})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attach the trailer metadata.
|
// Attach the trailer metadata.
|
||||||
for k, vv := range s.trailer {
|
headerFields = appendHeaderFieldsFromMD(headerFields, s.trailer)
|
||||||
// Clients don't tolerate reading restricted headers after some non restricted ones were sent.
|
trailingHeader := &headerFrame{
|
||||||
if isReservedHeader(k) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
for _, v := range vv {
|
|
||||||
headerFields = append(headerFields, hpack.HeaderField{Name: k, Value: encodeMetadataHeader(k, v)})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
trailer := &headerFrame{
|
|
||||||
streamID: s.id,
|
streamID: s.id,
|
||||||
hf: headerFields,
|
hf: headerFields,
|
||||||
endStream: true,
|
endStream: true,
|
||||||
@ -783,7 +790,8 @@ func (t *http2Server) WriteStatus(s *Stream, st *status.Status) error {
|
|||||||
atomic.StoreUint32(&t.resetPingStrikes, 1)
|
atomic.StoreUint32(&t.resetPingStrikes, 1)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
t.closeStream(s, false, 0, trailer, true)
|
s.hdrMu.Unlock()
|
||||||
|
t.closeStream(s, false, 0, trailingHeader, true)
|
||||||
if t.stats != nil {
|
if t.stats != nil {
|
||||||
t.stats.HandleRPC(s.Context(), &stats.OutTrailer{})
|
t.stats.HandleRPC(s.Context(), &stats.OutTrailer{})
|
||||||
}
|
}
|
||||||
@ -793,7 +801,7 @@ func (t *http2Server) WriteStatus(s *Stream, st *status.Status) error {
|
|||||||
// Write converts the data into HTTP2 data frame and sends it out. Non-nil error
|
// Write converts the data into HTTP2 data frame and sends it out. Non-nil error
|
||||||
// is returns if it fails (e.g., framing error, transport error).
|
// is returns if it fails (e.g., framing error, transport error).
|
||||||
func (t *http2Server) Write(s *Stream, hdr []byte, data []byte, opts *Options) error {
|
func (t *http2Server) Write(s *Stream, hdr []byte, data []byte, opts *Options) error {
|
||||||
if !s.headerOk { // Headers haven't been written yet.
|
if !s.isHeaderSent() { // Headers haven't been written yet.
|
||||||
if err := t.WriteHeader(s, nil); err != nil {
|
if err := t.WriteHeader(s, nil); err != nil {
|
||||||
// TODO(mmukhi, dfawley): Make sure this is the right code to return.
|
// TODO(mmukhi, dfawley): Make sure this is the right code to return.
|
||||||
return streamErrorf(codes.Internal, "transport: %v", err)
|
return streamErrorf(codes.Internal, "transport: %v", err)
|
||||||
@ -1123,14 +1131,12 @@ func (t *http2Server) getOutFlowWindow() int64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var rgen = rand.New(rand.NewSource(time.Now().UnixNano()))
|
|
||||||
|
|
||||||
func getJitter(v time.Duration) time.Duration {
|
func getJitter(v time.Duration) time.Duration {
|
||||||
if v == infinity {
|
if v == infinity {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
// Generate a jitter between +/- 10% of the value.
|
// Generate a jitter between +/- 10% of the value.
|
||||||
r := int64(v / 10)
|
r := int64(v / 10)
|
||||||
j := rgen.Int63n(2*r) - r
|
j := grpcrand.Int63n(2*r) - r
|
||||||
return time.Duration(j)
|
return time.Duration(j)
|
||||||
}
|
}
|
||||||
|
100
vendor/google.golang.org/grpc/transport/http_util.go
generated
vendored
100
vendor/google.golang.org/grpc/transport/http_util.go
generated
vendored
@ -28,6 +28,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
"golang.org/x/net/http2"
|
"golang.org/x/net/http2"
|
||||||
@ -45,12 +46,6 @@ const (
|
|||||||
// http2IOBufSize specifies the buffer size for sending frames.
|
// http2IOBufSize specifies the buffer size for sending frames.
|
||||||
defaultWriteBufSize = 32 * 1024
|
defaultWriteBufSize = 32 * 1024
|
||||||
defaultReadBufSize = 32 * 1024
|
defaultReadBufSize = 32 * 1024
|
||||||
// baseContentType is the base content-type for gRPC. This is a valid
|
|
||||||
// content-type on it's own, but can also include a content-subtype such as
|
|
||||||
// "proto" as a suffix after "+" or ";". See
|
|
||||||
// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests
|
|
||||||
// for more details.
|
|
||||||
baseContentType = "application/grpc"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -156,38 +151,6 @@ func isWhitelistedHeader(hdr string) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// contentSubtype returns the content-subtype for the given content-type. The
|
|
||||||
// given content-type must be a valid content-type that starts with
|
|
||||||
// "application/grpc". A content-subtype will follow "application/grpc" after a
|
|
||||||
// "+" or ";". See
|
|
||||||
// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests for
|
|
||||||
// more details.
|
|
||||||
//
|
|
||||||
// If contentType is not a valid content-type for gRPC, the boolean
|
|
||||||
// will be false, otherwise true. If content-type == "application/grpc",
|
|
||||||
// "application/grpc+", or "application/grpc;", the boolean will be true,
|
|
||||||
// but no content-subtype will be returned.
|
|
||||||
//
|
|
||||||
// contentType is assumed to be lowercase already.
|
|
||||||
func contentSubtype(contentType string) (string, bool) {
|
|
||||||
if contentType == baseContentType {
|
|
||||||
return "", true
|
|
||||||
}
|
|
||||||
if !strings.HasPrefix(contentType, baseContentType) {
|
|
||||||
return "", false
|
|
||||||
}
|
|
||||||
// guaranteed since != baseContentType and has baseContentType prefix
|
|
||||||
switch contentType[len(baseContentType)] {
|
|
||||||
case '+', ';':
|
|
||||||
// this will return true for "application/grpc+" or "application/grpc;"
|
|
||||||
// which the previous validContentType function tested to be valid, so we
|
|
||||||
// just say that no content-subtype is specified in this case
|
|
||||||
return contentType[len(baseContentType)+1:], true
|
|
||||||
default:
|
|
||||||
return "", false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// contentSubtype is assumed to be lowercase
|
// contentSubtype is assumed to be lowercase
|
||||||
func contentType(contentSubtype string) string {
|
func contentType(contentSubtype string) string {
|
||||||
if contentSubtype == "" {
|
if contentSubtype == "" {
|
||||||
@ -233,13 +196,7 @@ func decodeMetadataHeader(k, v string) (string, error) {
|
|||||||
return v, nil
|
return v, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *decodeState) decodeResponseHeader(frame *http2.MetaHeadersFrame) error {
|
func (d *decodeState) validate() error {
|
||||||
for _, hf := range frame.Fields {
|
|
||||||
if err := d.processHeaderField(hf); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If grpc status exists, no need to check further.
|
// If grpc status exists, no need to check further.
|
||||||
if d.rawStatusCode != nil || d.statusGen != nil {
|
if d.rawStatusCode != nil || d.statusGen != nil {
|
||||||
return nil
|
return nil
|
||||||
@ -437,16 +394,17 @@ func decodeTimeout(s string) (time.Duration, error) {
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
spaceByte = ' '
|
spaceByte = ' '
|
||||||
tildaByte = '~'
|
tildeByte = '~'
|
||||||
percentByte = '%'
|
percentByte = '%'
|
||||||
)
|
)
|
||||||
|
|
||||||
// encodeGrpcMessage is used to encode status code in header field
|
// encodeGrpcMessage is used to encode status code in header field
|
||||||
// "grpc-message".
|
// "grpc-message". It does percent encoding and also replaces invalid utf-8
|
||||||
// It checks to see if each individual byte in msg is an
|
// characters with Unicode replacement character.
|
||||||
// allowable byte, and then either percent encoding or passing it through.
|
//
|
||||||
// When percent encoding, the byte is converted into hexadecimal notation
|
// It checks to see if each individual byte in msg is an allowable byte, and
|
||||||
// with a '%' prepended.
|
// then either percent encoding or passing it through. When percent encoding,
|
||||||
|
// the byte is converted into hexadecimal notation with a '%' prepended.
|
||||||
func encodeGrpcMessage(msg string) string {
|
func encodeGrpcMessage(msg string) string {
|
||||||
if msg == "" {
|
if msg == "" {
|
||||||
return ""
|
return ""
|
||||||
@ -454,7 +412,7 @@ func encodeGrpcMessage(msg string) string {
|
|||||||
lenMsg := len(msg)
|
lenMsg := len(msg)
|
||||||
for i := 0; i < lenMsg; i++ {
|
for i := 0; i < lenMsg; i++ {
|
||||||
c := msg[i]
|
c := msg[i]
|
||||||
if !(c >= spaceByte && c < tildaByte && c != percentByte) {
|
if !(c >= spaceByte && c <= tildeByte && c != percentByte) {
|
||||||
return encodeGrpcMessageUnchecked(msg)
|
return encodeGrpcMessageUnchecked(msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -463,14 +421,26 @@ func encodeGrpcMessage(msg string) string {
|
|||||||
|
|
||||||
func encodeGrpcMessageUnchecked(msg string) string {
|
func encodeGrpcMessageUnchecked(msg string) string {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
lenMsg := len(msg)
|
for len(msg) > 0 {
|
||||||
for i := 0; i < lenMsg; i++ {
|
r, size := utf8.DecodeRuneInString(msg)
|
||||||
c := msg[i]
|
for _, b := range []byte(string(r)) {
|
||||||
if c >= spaceByte && c < tildaByte && c != percentByte {
|
if size > 1 {
|
||||||
buf.WriteByte(c)
|
// If size > 1, r is not ascii. Always do percent encoding.
|
||||||
} else {
|
buf.WriteString(fmt.Sprintf("%%%02X", b))
|
||||||
buf.WriteString(fmt.Sprintf("%%%02X", c))
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// The for loop is necessary even if size == 1. r could be
|
||||||
|
// utf8.RuneError.
|
||||||
|
//
|
||||||
|
// fmt.Sprintf("%%%02X", utf8.RuneError) gives "%FFFD".
|
||||||
|
if b >= spaceByte && b <= tildeByte && b != percentByte {
|
||||||
|
buf.WriteByte(b)
|
||||||
|
} else {
|
||||||
|
buf.WriteString(fmt.Sprintf("%%%02X", b))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
msg = msg[size:]
|
||||||
}
|
}
|
||||||
return buf.String()
|
return buf.String()
|
||||||
}
|
}
|
||||||
@ -531,10 +501,14 @@ func (w *bufWriter) Write(b []byte) (n int, err error) {
|
|||||||
if w.err != nil {
|
if w.err != nil {
|
||||||
return 0, w.err
|
return 0, w.err
|
||||||
}
|
}
|
||||||
n = copy(w.buf[w.offset:], b)
|
for len(b) > 0 {
|
||||||
w.offset += n
|
nn := copy(w.buf[w.offset:], b)
|
||||||
if w.offset >= w.batchSize {
|
b = b[nn:]
|
||||||
err = w.Flush()
|
w.offset += nn
|
||||||
|
n += nn
|
||||||
|
if w.offset >= w.batchSize {
|
||||||
|
err = w.Flush()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
35
vendor/google.golang.org/grpc/transport/stream.go
generated
vendored
Normal file
35
vendor/google.golang.org/grpc/transport/stream.go
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// +build !js !wasm
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2018 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package transport
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Read reads all p bytes from the wire for this stream.
|
||||||
|
func (s *Stream) Read(p []byte) (n int, err error) {
|
||||||
|
// Don't request a read if there was an error earlier
|
||||||
|
if er := s.trReader.(*transportReader).er; er != nil {
|
||||||
|
return 0, er
|
||||||
|
}
|
||||||
|
s.requestRead(len(p))
|
||||||
|
return io.ReadFull(s.trReader, p)
|
||||||
|
}
|
40
vendor/google.golang.org/grpc/transport/stream_js.go
generated
vendored
Normal file
40
vendor/google.golang.org/grpc/transport/stream_js.go
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
// +build js,wasm
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2018 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package transport
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Read reads all p bytes from the wire for this stream.
|
||||||
|
func (s *Stream) Read(p []byte) (n int, err error) {
|
||||||
|
// block until body has been set
|
||||||
|
select {
|
||||||
|
case <-s.ctx.Done():
|
||||||
|
return 0, s.ctx.Err()
|
||||||
|
case <-s.respChan:
|
||||||
|
if s.writeErr != nil {
|
||||||
|
return 0, s.writeErr
|
||||||
|
}
|
||||||
|
n, err := io.ReadFull(s.body, p)
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
}
|
55
vendor/google.golang.org/grpc/transport/transport.go
generated
vendored
55
vendor/google.golang.org/grpc/transport/transport.go
generated
vendored
@ -26,6 +26,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
"net/http"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
@ -185,13 +186,20 @@ type Stream struct {
|
|||||||
|
|
||||||
headerChan chan struct{} // closed to indicate the end of header metadata.
|
headerChan chan struct{} // closed to indicate the end of header metadata.
|
||||||
headerDone uint32 // set when headerChan is closed. Used to avoid closing headerChan multiple times.
|
headerDone uint32 // set when headerChan is closed. Used to avoid closing headerChan multiple times.
|
||||||
header metadata.MD // the received header metadata.
|
|
||||||
trailer metadata.MD // the key-value map of trailer metadata.
|
|
||||||
|
|
||||||
headerOk bool // becomes true from the first header is about to send
|
// hdrMu protects header and trailer metadata on the server-side.
|
||||||
state streamState
|
hdrMu sync.Mutex
|
||||||
|
header metadata.MD // the received header metadata.
|
||||||
|
trailer metadata.MD // the key-value map of trailer metadata.
|
||||||
|
|
||||||
status *status.Status // the status error received from the server
|
// On the server-side, headerSent is atomically set to 1 when the headers are sent out.
|
||||||
|
headerSent uint32
|
||||||
|
|
||||||
|
state streamState
|
||||||
|
|
||||||
|
// On client-side it is the status error received from the server.
|
||||||
|
// On server-side it is unused.
|
||||||
|
status *status.Status
|
||||||
|
|
||||||
bytesReceived uint32 // indicates whether any bytes have been received on this stream
|
bytesReceived uint32 // indicates whether any bytes have been received on this stream
|
||||||
unprocessed uint32 // set if the server sends a refused stream or GOAWAY including this stream
|
unprocessed uint32 // set if the server sends a refused stream or GOAWAY including this stream
|
||||||
@ -199,6 +207,24 @@ type Stream struct {
|
|||||||
// contentSubtype is the content-subtype for requests.
|
// contentSubtype is the content-subtype for requests.
|
||||||
// this must be lowercase or the behavior is undefined.
|
// this must be lowercase or the behavior is undefined.
|
||||||
contentSubtype string
|
contentSubtype string
|
||||||
|
|
||||||
|
// only used by WASM clients
|
||||||
|
req *http.Request
|
||||||
|
requestSent uint32 // indicates that the request has been sent
|
||||||
|
body io.ReadCloser
|
||||||
|
writeErr error
|
||||||
|
respChan chan struct{} // closed to indicate the body or writeErr has been set.
|
||||||
|
}
|
||||||
|
|
||||||
|
// isHeaderSent is only valid on the server-side.
|
||||||
|
func (s *Stream) isHeaderSent() bool {
|
||||||
|
return atomic.LoadUint32(&s.headerSent) == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// updateHeaderSent updates headerSent and returns true
|
||||||
|
// if it was alreay set. It is valid only on server-side.
|
||||||
|
func (s *Stream) updateHeaderSent() bool {
|
||||||
|
return atomic.SwapUint32(&s.headerSent, 1) == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Stream) swapState(st streamState) streamState {
|
func (s *Stream) swapState(st streamState) streamState {
|
||||||
@ -313,10 +339,12 @@ func (s *Stream) SetHeader(md metadata.MD) error {
|
|||||||
if md.Len() == 0 {
|
if md.Len() == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if s.headerOk || atomic.LoadUint32((*uint32)(&s.state)) == uint32(streamDone) {
|
if s.isHeaderSent() || s.getState() == streamDone {
|
||||||
return ErrIllegalHeaderWrite
|
return ErrIllegalHeaderWrite
|
||||||
}
|
}
|
||||||
|
s.hdrMu.Lock()
|
||||||
s.header = metadata.Join(s.header, md)
|
s.header = metadata.Join(s.header, md)
|
||||||
|
s.hdrMu.Unlock()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,7 +363,12 @@ func (s *Stream) SetTrailer(md metadata.MD) error {
|
|||||||
if md.Len() == 0 {
|
if md.Len() == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
if s.getState() == streamDone {
|
||||||
|
return ErrIllegalHeaderWrite
|
||||||
|
}
|
||||||
|
s.hdrMu.Lock()
|
||||||
s.trailer = metadata.Join(s.trailer, md)
|
s.trailer = metadata.Join(s.trailer, md)
|
||||||
|
s.hdrMu.Unlock()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,16 +376,6 @@ func (s *Stream) write(m recvMsg) {
|
|||||||
s.buf.put(m)
|
s.buf.put(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read reads all p bytes from the wire for this stream.
|
|
||||||
func (s *Stream) Read(p []byte) (n int, err error) {
|
|
||||||
// Don't request a read if there was an error earlier
|
|
||||||
if er := s.trReader.(*transportReader).er; er != nil {
|
|
||||||
return 0, er
|
|
||||||
}
|
|
||||||
s.requestRead(len(p))
|
|
||||||
return io.ReadFull(s.trReader, p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// tranportReader reads all the data available for this Stream from the transport and
|
// tranportReader reads all the data available for this Stream from the transport and
|
||||||
// passes them into the decoder, which converts them into a gRPC message stream.
|
// passes them into the decoder, which converts them into a gRPC message stream.
|
||||||
// The error is io.EOF when the stream is done or another non-nil error if
|
// The error is io.EOF when the stream is done or another non-nil error if
|
||||||
|
22
vendor/google.golang.org/grpc/version.go
generated
vendored
Normal file
22
vendor/google.golang.org/grpc/version.go
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2018 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package grpc
|
||||||
|
|
||||||
|
// Version is the current grpc version.
|
||||||
|
const Version = "1.14.0-dev"
|
3
vendor/google.golang.org/grpc/vet.sh
generated
vendored
3
vendor/google.golang.org/grpc/vet.sh
generated
vendored
@ -54,7 +54,8 @@ if git status --porcelain | read; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
git ls-files "*.go" | xargs grep -L "\(Copyright [0-9]\{4,\} gRPC authors\)\|DO NOT EDIT" 2>&1 | tee /dev/stderr | (! read)
|
git ls-files "*.go" | xargs grep -L "\(Copyright [0-9]\{4,\} gRPC authors\)\|DO NOT EDIT" 2>&1 | tee /dev/stderr | (! read)
|
||||||
git ls-files "*.go" | xargs grep -l "\"unsafe\"" 2>&1 | (! grep -v '_test.go') | tee /dev/stderr | (! read)
|
git ls-files "*.go" | xargs grep -l '"unsafe"' 2>&1 | (! grep -v '_test.go') | tee /dev/stderr | (! read)
|
||||||
|
git ls-files "*.go" | xargs grep -l '"math/rand"' 2>&1 | (! grep -v '^examples\|^stress\|grpcrand') | tee /dev/stderr | (! read)
|
||||||
gofmt -s -d -l . 2>&1 | tee /dev/stderr | (! read)
|
gofmt -s -d -l . 2>&1 | tee /dev/stderr | (! read)
|
||||||
goimports -l . 2>&1 | tee /dev/stderr | (! read)
|
goimports -l . 2>&1 | tee /dev/stderr | (! read)
|
||||||
golint ./... 2>&1 | (grep -vE "(_mock|\.pb)\.go:" || true) | tee /dev/stderr | (! read)
|
golint ./... 2>&1 | (grep -vE "(_mock|\.pb)\.go:" || true) | tee /dev/stderr | (! read)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user