mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-12-18 11:00:25 +00:00
rebase: bump google.golang.org/grpc from 1.45.0 to 1.46.0
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.45.0 to 1.46.0. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.45.0...v1.46.0) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
parent
70fc6db2cf
commit
b11951a710
2
go.mod
2
go.mod
@ -26,7 +26,7 @@ require (
|
|||||||
github.com/stretchr/testify v1.7.1
|
github.com/stretchr/testify v1.7.1
|
||||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
|
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
|
||||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9
|
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9
|
||||||
google.golang.org/grpc v1.45.0
|
google.golang.org/grpc v1.46.0
|
||||||
google.golang.org/protobuf v1.28.0
|
google.golang.org/protobuf v1.28.0
|
||||||
k8s.io/api v0.23.5
|
k8s.io/api v0.23.5
|
||||||
k8s.io/apimachinery v0.23.5
|
k8s.io/apimachinery v0.23.5
|
||||||
|
7
go.sum
7
go.sum
@ -210,6 +210,7 @@ github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XP
|
|||||||
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||||
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||||
|
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||||
github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk=
|
github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk=
|
||||||
@ -308,6 +309,7 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
|
|||||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
|
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
||||||
|
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
github.com/euank/go-kmsg-parser v2.0.0+incompatible/go.mod h1:MhmAMZ8V4CYH4ybgdRwPr2TU5ThnS43puaKEMpja1uw=
|
github.com/euank/go-kmsg-parser v2.0.0+incompatible/go.mod h1:MhmAMZ8V4CYH4ybgdRwPr2TU5ThnS43puaKEMpja1uw=
|
||||||
github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ=
|
github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ=
|
||||||
@ -451,6 +453,7 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
|
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
|
||||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||||
@ -1635,8 +1638,8 @@ google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ
|
|||||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||||
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||||
google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
|
google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
|
||||||
google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M=
|
google.golang.org/grpc v1.46.0 h1:oCjezcn6g6A75TGoKYBPgKmVBLexhYLM6MebdrPApP8=
|
||||||
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
|
google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
|
||||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
|
3
vendor/google.golang.org/grpc/balancer/balancer.go
generated
vendored
3
vendor/google.golang.org/grpc/balancer/balancer.go
generated
vendored
@ -27,6 +27,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"google.golang.org/grpc/channelz"
|
||||||
"google.golang.org/grpc/connectivity"
|
"google.golang.org/grpc/connectivity"
|
||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
"google.golang.org/grpc/internal"
|
"google.golang.org/grpc/internal"
|
||||||
@ -192,7 +193,7 @@ type BuildOptions struct {
|
|||||||
// server can ignore this field.
|
// server can ignore this field.
|
||||||
Authority string
|
Authority string
|
||||||
// ChannelzParentID is the parent ClientConn's channelz ID.
|
// ChannelzParentID is the parent ClientConn's channelz ID.
|
||||||
ChannelzParentID int64
|
ChannelzParentID *channelz.Identifier
|
||||||
// CustomUserAgent is the custom user agent set on the parent ClientConn.
|
// CustomUserAgent is the custom user agent set on the parent ClientConn.
|
||||||
// The balancer should set the same custom user agent if it creates a
|
// The balancer should set the same custom user agent if it creates a
|
||||||
// ClientConn.
|
// ClientConn.
|
||||||
|
326
vendor/google.golang.org/grpc/balancer_conn_wrappers.go
generated
vendored
326
vendor/google.golang.org/grpc/balancer_conn_wrappers.go
generated
vendored
@ -20,130 +20,178 @@ package grpc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"google.golang.org/grpc/balancer"
|
"google.golang.org/grpc/balancer"
|
||||||
"google.golang.org/grpc/connectivity"
|
"google.golang.org/grpc/connectivity"
|
||||||
|
"google.golang.org/grpc/internal/balancer/gracefulswitch"
|
||||||
"google.golang.org/grpc/internal/buffer"
|
"google.golang.org/grpc/internal/buffer"
|
||||||
"google.golang.org/grpc/internal/channelz"
|
"google.golang.org/grpc/internal/channelz"
|
||||||
"google.golang.org/grpc/internal/grpcsync"
|
"google.golang.org/grpc/internal/grpcsync"
|
||||||
"google.golang.org/grpc/resolver"
|
"google.golang.org/grpc/resolver"
|
||||||
)
|
)
|
||||||
|
|
||||||
// scStateUpdate contains the subConn and the new state it changed to.
|
// ccBalancerWrapper sits between the ClientConn and the Balancer.
|
||||||
|
//
|
||||||
|
// ccBalancerWrapper implements methods corresponding to the ones on the
|
||||||
|
// balancer.Balancer interface. The ClientConn is free to call these methods
|
||||||
|
// concurrently and the ccBalancerWrapper ensures that calls from the ClientConn
|
||||||
|
// to the Balancer happen synchronously and in order.
|
||||||
|
//
|
||||||
|
// ccBalancerWrapper also implements the balancer.ClientConn interface and is
|
||||||
|
// passed to the Balancer implementations. It invokes unexported methods on the
|
||||||
|
// ClientConn to handle these calls from the Balancer.
|
||||||
|
//
|
||||||
|
// It uses the gracefulswitch.Balancer internally to ensure that balancer
|
||||||
|
// switches happen in a graceful manner.
|
||||||
|
type ccBalancerWrapper struct {
|
||||||
|
cc *ClientConn
|
||||||
|
|
||||||
|
// Since these fields are accessed only from handleXxx() methods which are
|
||||||
|
// synchronized by the watcher goroutine, we do not need a mutex to protect
|
||||||
|
// these fields.
|
||||||
|
balancer *gracefulswitch.Balancer
|
||||||
|
curBalancerName string
|
||||||
|
|
||||||
|
updateCh *buffer.Unbounded // Updates written on this channel are processed by watcher().
|
||||||
|
resultCh *buffer.Unbounded // Results of calls to UpdateClientConnState() are pushed here.
|
||||||
|
closed *grpcsync.Event // Indicates if close has been called.
|
||||||
|
done *grpcsync.Event // Indicates if close has completed its work.
|
||||||
|
}
|
||||||
|
|
||||||
|
// newCCBalancerWrapper creates a new balancer wrapper. The underlying balancer
|
||||||
|
// is not created until the switchTo() method is invoked.
|
||||||
|
func newCCBalancerWrapper(cc *ClientConn, bopts balancer.BuildOptions) *ccBalancerWrapper {
|
||||||
|
ccb := &ccBalancerWrapper{
|
||||||
|
cc: cc,
|
||||||
|
updateCh: buffer.NewUnbounded(),
|
||||||
|
resultCh: buffer.NewUnbounded(),
|
||||||
|
closed: grpcsync.NewEvent(),
|
||||||
|
done: grpcsync.NewEvent(),
|
||||||
|
}
|
||||||
|
go ccb.watcher()
|
||||||
|
ccb.balancer = gracefulswitch.NewBalancer(ccb, bopts)
|
||||||
|
return ccb
|
||||||
|
}
|
||||||
|
|
||||||
|
// The following xxxUpdate structs wrap the arguments received as part of the
|
||||||
|
// corresponding update. The watcher goroutine uses the 'type' of the update to
|
||||||
|
// invoke the appropriate handler routine to handle the update.
|
||||||
|
|
||||||
|
type ccStateUpdate struct {
|
||||||
|
ccs *balancer.ClientConnState
|
||||||
|
}
|
||||||
|
|
||||||
type scStateUpdate struct {
|
type scStateUpdate struct {
|
||||||
sc balancer.SubConn
|
sc balancer.SubConn
|
||||||
state connectivity.State
|
state connectivity.State
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
// exitIdle contains no data and is just a signal sent on the updateCh in
|
type exitIdleUpdate struct{}
|
||||||
// ccBalancerWrapper to instruct the balancer to exit idle.
|
|
||||||
type exitIdle struct{}
|
|
||||||
|
|
||||||
// ccBalancerWrapper is a wrapper on top of cc for balancers.
|
type resolverErrorUpdate struct {
|
||||||
// It implements balancer.ClientConn interface.
|
err error
|
||||||
type ccBalancerWrapper struct {
|
|
||||||
cc *ClientConn
|
|
||||||
balancerMu sync.Mutex // synchronizes calls to the balancer
|
|
||||||
balancer balancer.Balancer
|
|
||||||
hasExitIdle bool
|
|
||||||
updateCh *buffer.Unbounded
|
|
||||||
closed *grpcsync.Event
|
|
||||||
done *grpcsync.Event
|
|
||||||
|
|
||||||
mu sync.Mutex
|
|
||||||
subConns map[*acBalancerWrapper]struct{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newCCBalancerWrapper(cc *ClientConn, b balancer.Builder, bopts balancer.BuildOptions) *ccBalancerWrapper {
|
type switchToUpdate struct {
|
||||||
ccb := &ccBalancerWrapper{
|
name string
|
||||||
cc: cc,
|
|
||||||
updateCh: buffer.NewUnbounded(),
|
|
||||||
closed: grpcsync.NewEvent(),
|
|
||||||
done: grpcsync.NewEvent(),
|
|
||||||
subConns: make(map[*acBalancerWrapper]struct{}),
|
|
||||||
}
|
|
||||||
go ccb.watcher()
|
|
||||||
ccb.balancer = b.Build(ccb, bopts)
|
|
||||||
_, ccb.hasExitIdle = ccb.balancer.(balancer.ExitIdler)
|
|
||||||
return ccb
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// watcher balancer functions sequentially, so the balancer can be implemented
|
type subConnUpdate struct {
|
||||||
// lock-free.
|
acbw *acBalancerWrapper
|
||||||
|
}
|
||||||
|
|
||||||
|
// watcher is a long-running goroutine which reads updates from a channel and
|
||||||
|
// invokes corresponding methods on the underlying balancer. It ensures that
|
||||||
|
// these methods are invoked in a synchronous fashion. It also ensures that
|
||||||
|
// these methods are invoked in the order in which the updates were received.
|
||||||
func (ccb *ccBalancerWrapper) watcher() {
|
func (ccb *ccBalancerWrapper) watcher() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case t := <-ccb.updateCh.Get():
|
case u := <-ccb.updateCh.Get():
|
||||||
ccb.updateCh.Load()
|
ccb.updateCh.Load()
|
||||||
if ccb.closed.HasFired() {
|
if ccb.closed.HasFired() {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
switch u := t.(type) {
|
switch update := u.(type) {
|
||||||
|
case *ccStateUpdate:
|
||||||
|
ccb.handleClientConnStateChange(update.ccs)
|
||||||
case *scStateUpdate:
|
case *scStateUpdate:
|
||||||
ccb.balancerMu.Lock()
|
ccb.handleSubConnStateChange(update)
|
||||||
ccb.balancer.UpdateSubConnState(u.sc, balancer.SubConnState{ConnectivityState: u.state, ConnectionError: u.err})
|
case *exitIdleUpdate:
|
||||||
ccb.balancerMu.Unlock()
|
ccb.handleExitIdle()
|
||||||
case *acBalancerWrapper:
|
case *resolverErrorUpdate:
|
||||||
ccb.mu.Lock()
|
ccb.handleResolverError(update.err)
|
||||||
if ccb.subConns != nil {
|
case *switchToUpdate:
|
||||||
delete(ccb.subConns, u)
|
ccb.handleSwitchTo(update.name)
|
||||||
ccb.cc.removeAddrConn(u.getAddrConn(), errConnDrain)
|
case *subConnUpdate:
|
||||||
}
|
ccb.handleRemoveSubConn(update.acbw)
|
||||||
ccb.mu.Unlock()
|
|
||||||
case exitIdle:
|
|
||||||
if ccb.cc.GetState() == connectivity.Idle {
|
|
||||||
if ei, ok := ccb.balancer.(balancer.ExitIdler); ok {
|
|
||||||
// We already checked that the balancer implements
|
|
||||||
// ExitIdle before pushing the event to updateCh, but
|
|
||||||
// check conditionally again as defensive programming.
|
|
||||||
ccb.balancerMu.Lock()
|
|
||||||
ei.ExitIdle()
|
|
||||||
ccb.balancerMu.Unlock()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
logger.Errorf("ccBalancerWrapper.watcher: unknown update %+v, type %T", t, t)
|
logger.Errorf("ccBalancerWrapper.watcher: unknown update %+v, type %T", update, update)
|
||||||
}
|
}
|
||||||
case <-ccb.closed.Done():
|
case <-ccb.closed.Done():
|
||||||
}
|
}
|
||||||
|
|
||||||
if ccb.closed.HasFired() {
|
if ccb.closed.HasFired() {
|
||||||
ccb.balancerMu.Lock()
|
ccb.handleClose()
|
||||||
ccb.balancer.Close()
|
|
||||||
ccb.balancerMu.Unlock()
|
|
||||||
ccb.mu.Lock()
|
|
||||||
scs := ccb.subConns
|
|
||||||
ccb.subConns = nil
|
|
||||||
ccb.mu.Unlock()
|
|
||||||
ccb.UpdateState(balancer.State{ConnectivityState: connectivity.Connecting, Picker: nil})
|
|
||||||
ccb.done.Fire()
|
|
||||||
// Fire done before removing the addr conns. We can safely unblock
|
|
||||||
// ccb.close and allow the removeAddrConns to happen
|
|
||||||
// asynchronously.
|
|
||||||
for acbw := range scs {
|
|
||||||
ccb.cc.removeAddrConn(acbw.getAddrConn(), errConnDrain)
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ccb *ccBalancerWrapper) close() {
|
// updateClientConnState is invoked by grpc to push a ClientConnState update to
|
||||||
ccb.closed.Fire()
|
// the underlying balancer.
|
||||||
<-ccb.done.Done()
|
//
|
||||||
}
|
// Unlike other methods invoked by grpc to push updates to the underlying
|
||||||
|
// balancer, this method cannot simply push the update onto the update channel
|
||||||
|
// and return. It needs to return the error returned by the underlying balancer
|
||||||
|
// back to grpc which propagates that to the resolver.
|
||||||
|
func (ccb *ccBalancerWrapper) updateClientConnState(ccs *balancer.ClientConnState) error {
|
||||||
|
ccb.updateCh.Put(&ccStateUpdate{ccs: ccs})
|
||||||
|
|
||||||
func (ccb *ccBalancerWrapper) exitIdle() bool {
|
var res interface{}
|
||||||
if !ccb.hasExitIdle {
|
select {
|
||||||
return false
|
case res = <-ccb.resultCh.Get():
|
||||||
|
ccb.resultCh.Load()
|
||||||
|
case <-ccb.closed.Done():
|
||||||
|
// Return early if the balancer wrapper is closed while we are waiting for
|
||||||
|
// the underlying balancer to process a ClientConnState update.
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
ccb.updateCh.Put(exitIdle{})
|
// If the returned error is nil, attempting to type assert to error leads to
|
||||||
return true
|
// panic. So, this needs to handled separately.
|
||||||
|
if res == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return res.(error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ccb *ccBalancerWrapper) handleSubConnStateChange(sc balancer.SubConn, s connectivity.State, err error) {
|
// handleClientConnStateChange handles a ClientConnState update from the update
|
||||||
|
// channel and invokes the appropriate method on the underlying balancer.
|
||||||
|
//
|
||||||
|
// If the addresses specified in the update contain addresses of type "grpclb"
|
||||||
|
// and the selected LB policy is not "grpclb", these addresses will be filtered
|
||||||
|
// out and ccs will be modified with the updated address list.
|
||||||
|
func (ccb *ccBalancerWrapper) handleClientConnStateChange(ccs *balancer.ClientConnState) {
|
||||||
|
if ccb.curBalancerName != grpclbName {
|
||||||
|
// Filter any grpclb addresses since we don't have the grpclb balancer.
|
||||||
|
var addrs []resolver.Address
|
||||||
|
for _, addr := range ccs.ResolverState.Addresses {
|
||||||
|
if addr.Type == resolver.GRPCLB {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
addrs = append(addrs, addr)
|
||||||
|
}
|
||||||
|
ccs.ResolverState.Addresses = addrs
|
||||||
|
}
|
||||||
|
ccb.resultCh.Put(ccb.balancer.UpdateClientConnState(*ccs))
|
||||||
|
}
|
||||||
|
|
||||||
|
// updateSubConnState is invoked by grpc to push a subConn state update to the
|
||||||
|
// underlying balancer.
|
||||||
|
func (ccb *ccBalancerWrapper) updateSubConnState(sc balancer.SubConn, s connectivity.State, err error) {
|
||||||
// When updating addresses for a SubConn, if the address in use is not in
|
// When updating addresses for a SubConn, if the address in use is not in
|
||||||
// the new addresses, the old ac will be tearDown() and a new ac will be
|
// the new addresses, the old ac will be tearDown() and a new ac will be
|
||||||
// created. tearDown() generates a state change with Shutdown state, we
|
// created. tearDown() generates a state change with Shutdown state, we
|
||||||
@ -161,44 +209,125 @@ func (ccb *ccBalancerWrapper) handleSubConnStateChange(sc balancer.SubConn, s co
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ccb *ccBalancerWrapper) updateClientConnState(ccs *balancer.ClientConnState) error {
|
// handleSubConnStateChange handles a SubConnState update from the update
|
||||||
ccb.balancerMu.Lock()
|
// channel and invokes the appropriate method on the underlying balancer.
|
||||||
defer ccb.balancerMu.Unlock()
|
func (ccb *ccBalancerWrapper) handleSubConnStateChange(update *scStateUpdate) {
|
||||||
return ccb.balancer.UpdateClientConnState(*ccs)
|
ccb.balancer.UpdateSubConnState(update.sc, balancer.SubConnState{ConnectivityState: update.state, ConnectionError: update.err})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ccb *ccBalancerWrapper) exitIdle() {
|
||||||
|
ccb.updateCh.Put(&exitIdleUpdate{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ccb *ccBalancerWrapper) handleExitIdle() {
|
||||||
|
if ccb.cc.GetState() != connectivity.Idle {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ccb.balancer.ExitIdle()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ccb *ccBalancerWrapper) resolverError(err error) {
|
func (ccb *ccBalancerWrapper) resolverError(err error) {
|
||||||
ccb.balancerMu.Lock()
|
ccb.updateCh.Put(&resolverErrorUpdate{err: err})
|
||||||
defer ccb.balancerMu.Unlock()
|
}
|
||||||
|
|
||||||
|
func (ccb *ccBalancerWrapper) handleResolverError(err error) {
|
||||||
ccb.balancer.ResolverError(err)
|
ccb.balancer.ResolverError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// switchTo is invoked by grpc to instruct the balancer wrapper to switch to the
|
||||||
|
// LB policy identified by name.
|
||||||
|
//
|
||||||
|
// ClientConn calls newCCBalancerWrapper() at creation time. Upon receipt of the
|
||||||
|
// first good update from the name resolver, it determines the LB policy to use
|
||||||
|
// and invokes the switchTo() method. Upon receipt of every subsequent update
|
||||||
|
// from the name resolver, it invokes this method.
|
||||||
|
//
|
||||||
|
// the ccBalancerWrapper keeps track of the current LB policy name, and skips
|
||||||
|
// the graceful balancer switching process if the name does not change.
|
||||||
|
func (ccb *ccBalancerWrapper) switchTo(name string) {
|
||||||
|
ccb.updateCh.Put(&switchToUpdate{name: name})
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleSwitchTo handles a balancer switch update from the update channel. It
|
||||||
|
// calls the SwitchTo() method on the gracefulswitch.Balancer with a
|
||||||
|
// balancer.Builder corresponding to name. If no balancer.Builder is registered
|
||||||
|
// for the given name, it uses the default LB policy which is "pick_first".
|
||||||
|
func (ccb *ccBalancerWrapper) handleSwitchTo(name string) {
|
||||||
|
// TODO: Other languages use case-insensitive balancer registries. We should
|
||||||
|
// switch as well. See: https://github.com/grpc/grpc-go/issues/5288.
|
||||||
|
if strings.EqualFold(ccb.curBalancerName, name) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Ensure that name is a registered LB policy when we get here.
|
||||||
|
// We currently only validate the `loadBalancingConfig` field. We need to do
|
||||||
|
// the same for the `loadBalancingPolicy` field and reject the service config
|
||||||
|
// if the specified policy is not registered.
|
||||||
|
builder := balancer.Get(name)
|
||||||
|
if builder == nil {
|
||||||
|
channelz.Warningf(logger, ccb.cc.channelzID, "Channel switches to new LB policy %q, since the specified LB policy %q was not registered", PickFirstBalancerName, name)
|
||||||
|
builder = newPickfirstBuilder()
|
||||||
|
} else {
|
||||||
|
channelz.Infof(logger, ccb.cc.channelzID, "Channel switches to new LB policy %q", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ccb.balancer.SwitchTo(builder); err != nil {
|
||||||
|
channelz.Errorf(logger, ccb.cc.channelzID, "Channel failed to build new LB policy %q: %v", name, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ccb.curBalancerName = builder.Name()
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleRemoveSucConn handles a request from the underlying balancer to remove
|
||||||
|
// a subConn.
|
||||||
|
//
|
||||||
|
// See comments in RemoveSubConn() for more details.
|
||||||
|
func (ccb *ccBalancerWrapper) handleRemoveSubConn(acbw *acBalancerWrapper) {
|
||||||
|
ccb.cc.removeAddrConn(acbw.getAddrConn(), errConnDrain)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ccb *ccBalancerWrapper) close() {
|
||||||
|
ccb.closed.Fire()
|
||||||
|
<-ccb.done.Done()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ccb *ccBalancerWrapper) handleClose() {
|
||||||
|
ccb.balancer.Close()
|
||||||
|
ccb.done.Fire()
|
||||||
|
}
|
||||||
|
|
||||||
func (ccb *ccBalancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) {
|
func (ccb *ccBalancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) {
|
||||||
if len(addrs) <= 0 {
|
if len(addrs) <= 0 {
|
||||||
return nil, fmt.Errorf("grpc: cannot create SubConn with empty address list")
|
return nil, fmt.Errorf("grpc: cannot create SubConn with empty address list")
|
||||||
}
|
}
|
||||||
ccb.mu.Lock()
|
|
||||||
defer ccb.mu.Unlock()
|
|
||||||
if ccb.subConns == nil {
|
|
||||||
return nil, fmt.Errorf("grpc: ClientConn balancer wrapper was closed")
|
|
||||||
}
|
|
||||||
ac, err := ccb.cc.newAddrConn(addrs, opts)
|
ac, err := ccb.cc.newAddrConn(addrs, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
channelz.Warningf(logger, ccb.cc.channelzID, "acBalancerWrapper: NewSubConn: failed to newAddrConn: %v", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
acbw := &acBalancerWrapper{ac: ac}
|
acbw := &acBalancerWrapper{ac: ac}
|
||||||
acbw.ac.mu.Lock()
|
acbw.ac.mu.Lock()
|
||||||
ac.acbw = acbw
|
ac.acbw = acbw
|
||||||
acbw.ac.mu.Unlock()
|
acbw.ac.mu.Unlock()
|
||||||
ccb.subConns[acbw] = struct{}{}
|
|
||||||
return acbw, nil
|
return acbw, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ccb *ccBalancerWrapper) RemoveSubConn(sc balancer.SubConn) {
|
func (ccb *ccBalancerWrapper) RemoveSubConn(sc balancer.SubConn) {
|
||||||
// The RemoveSubConn() is handled in the run() goroutine, to avoid deadlock
|
// Before we switched the ccBalancerWrapper to use gracefulswitch.Balancer, it
|
||||||
// during switchBalancer() if the old balancer calls RemoveSubConn() in its
|
// was required to handle the RemoveSubConn() method asynchronously by pushing
|
||||||
// Close().
|
// the update onto the update channel. This was done to avoid a deadlock as
|
||||||
ccb.updateCh.Put(sc)
|
// switchBalancer() was holding cc.mu when calling Close() on the old
|
||||||
|
// balancer, which would in turn call RemoveSubConn().
|
||||||
|
//
|
||||||
|
// With the use of gracefulswitch.Balancer in ccBalancerWrapper, handling this
|
||||||
|
// asynchronously is probably not required anymore since the switchTo() method
|
||||||
|
// handles the balancer switch by pushing the update onto the channel.
|
||||||
|
// TODO(easwars): Handle this inline.
|
||||||
|
acbw, ok := sc.(*acBalancerWrapper)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ccb.updateCh.Put(&subConnUpdate{acbw: acbw})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ccb *ccBalancerWrapper) UpdateAddresses(sc balancer.SubConn, addrs []resolver.Address) {
|
func (ccb *ccBalancerWrapper) UpdateAddresses(sc balancer.SubConn, addrs []resolver.Address) {
|
||||||
@ -210,11 +339,6 @@ func (ccb *ccBalancerWrapper) UpdateAddresses(sc balancer.SubConn, addrs []resol
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ccb *ccBalancerWrapper) UpdateState(s balancer.State) {
|
func (ccb *ccBalancerWrapper) UpdateState(s balancer.State) {
|
||||||
ccb.mu.Lock()
|
|
||||||
defer ccb.mu.Unlock()
|
|
||||||
if ccb.subConns == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Update picker before updating state. Even though the ordering here does
|
// Update picker before updating state. Even though the ordering here does
|
||||||
// not matter, it can lead to multiple calls of Pick in the common start-up
|
// not matter, it can lead to multiple calls of Pick in the common start-up
|
||||||
// case where we wait for ready and then perform an RPC. If the picker is
|
// case where we wait for ready and then perform an RPC. If the picker is
|
||||||
|
36
vendor/google.golang.org/grpc/channelz/channelz.go
generated
vendored
Normal file
36
vendor/google.golang.org/grpc/channelz/channelz.go
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2020 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 channelz exports internals of the channelz implementation as required
|
||||||
|
// by other gRPC packages.
|
||||||
|
//
|
||||||
|
// The implementation of the channelz spec as defined in
|
||||||
|
// https://github.com/grpc/proposal/blob/master/A14-channelz.md, is provided by
|
||||||
|
// the `internal/channelz` package.
|
||||||
|
//
|
||||||
|
// Experimental
|
||||||
|
//
|
||||||
|
// Notice: All APIs in this package are experimental and may be removed in a
|
||||||
|
// later release.
|
||||||
|
package channelz
|
||||||
|
|
||||||
|
import "google.golang.org/grpc/internal/channelz"
|
||||||
|
|
||||||
|
// Identifier is an opaque identifier which uniquely identifies an entity in the
|
||||||
|
// channelz database.
|
||||||
|
type Identifier = channelz.Identifier
|
312
vendor/google.golang.org/grpc/clientconn.go
generated
vendored
312
vendor/google.golang.org/grpc/clientconn.go
generated
vendored
@ -159,23 +159,20 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if channelz.IsOn() {
|
pid := cc.dopts.channelzParentID
|
||||||
if cc.dopts.channelzParentID != 0 {
|
cc.channelzID = channelz.RegisterChannel(&channelzChannel{cc}, pid, target)
|
||||||
cc.channelzID = channelz.RegisterChannel(&channelzChannel{cc}, cc.dopts.channelzParentID, target)
|
ted := &channelz.TraceEventDesc{
|
||||||
channelz.AddTraceEvent(logger, cc.channelzID, 0, &channelz.TraceEventDesc{
|
Desc: "Channel created",
|
||||||
Desc: "Channel Created",
|
Severity: channelz.CtInfo,
|
||||||
Severity: channelz.CtInfo,
|
|
||||||
Parent: &channelz.TraceEventDesc{
|
|
||||||
Desc: fmt.Sprintf("Nested Channel(id:%d) created", cc.channelzID),
|
|
||||||
Severity: channelz.CtInfo,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
cc.channelzID = channelz.RegisterChannel(&channelzChannel{cc}, 0, target)
|
|
||||||
channelz.Info(logger, cc.channelzID, "Channel Created")
|
|
||||||
}
|
|
||||||
cc.csMgr.channelzID = cc.channelzID
|
|
||||||
}
|
}
|
||||||
|
if cc.dopts.channelzParentID != nil {
|
||||||
|
ted.Parent = &channelz.TraceEventDesc{
|
||||||
|
Desc: fmt.Sprintf("Nested Channel(id:%d) created", cc.channelzID.Int()),
|
||||||
|
Severity: channelz.CtInfo,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
channelz.AddTraceEvent(logger, cc.channelzID, 1, ted)
|
||||||
|
cc.csMgr.channelzID = cc.channelzID
|
||||||
|
|
||||||
if cc.dopts.copts.TransportCredentials == nil && cc.dopts.copts.CredsBundle == nil {
|
if cc.dopts.copts.TransportCredentials == nil && cc.dopts.copts.CredsBundle == nil {
|
||||||
return nil, errNoTransportSecurity
|
return nil, errNoTransportSecurity
|
||||||
@ -281,7 +278,7 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
|
|||||||
if creds := cc.dopts.copts.TransportCredentials; creds != nil {
|
if creds := cc.dopts.copts.TransportCredentials; creds != nil {
|
||||||
credsClone = creds.Clone()
|
credsClone = creds.Clone()
|
||||||
}
|
}
|
||||||
cc.balancerBuildOpts = balancer.BuildOptions{
|
cc.balancerWrapper = newCCBalancerWrapper(cc, balancer.BuildOptions{
|
||||||
DialCreds: credsClone,
|
DialCreds: credsClone,
|
||||||
CredsBundle: cc.dopts.copts.CredsBundle,
|
CredsBundle: cc.dopts.copts.CredsBundle,
|
||||||
Dialer: cc.dopts.copts.Dialer,
|
Dialer: cc.dopts.copts.Dialer,
|
||||||
@ -289,7 +286,7 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
|
|||||||
CustomUserAgent: cc.dopts.copts.UserAgent,
|
CustomUserAgent: cc.dopts.copts.UserAgent,
|
||||||
ChannelzParentID: cc.channelzID,
|
ChannelzParentID: cc.channelzID,
|
||||||
Target: cc.parsedTarget,
|
Target: cc.parsedTarget,
|
||||||
}
|
})
|
||||||
|
|
||||||
// Build the resolver.
|
// Build the resolver.
|
||||||
rWrapper, err := newCCResolverWrapper(cc, resolverBuilder)
|
rWrapper, err := newCCResolverWrapper(cc, resolverBuilder)
|
||||||
@ -398,7 +395,7 @@ type connectivityStateManager struct {
|
|||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
state connectivity.State
|
state connectivity.State
|
||||||
notifyChan chan struct{}
|
notifyChan chan struct{}
|
||||||
channelzID int64
|
channelzID *channelz.Identifier
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateState updates the connectivity.State of ClientConn.
|
// updateState updates the connectivity.State of ClientConn.
|
||||||
@ -464,34 +461,36 @@ var _ ClientConnInterface = (*ClientConn)(nil)
|
|||||||
// handshakes. It also handles errors on established connections by
|
// handshakes. It also handles errors on established connections by
|
||||||
// re-resolving the name and reconnecting.
|
// re-resolving the name and reconnecting.
|
||||||
type ClientConn struct {
|
type ClientConn struct {
|
||||||
ctx context.Context
|
ctx context.Context // Initialized using the background context at dial time.
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc // Cancelled on close.
|
||||||
|
|
||||||
target string
|
// The following are initialized at dial time, and are read-only after that.
|
||||||
parsedTarget resolver.Target
|
target string // User's dial target.
|
||||||
authority string
|
parsedTarget resolver.Target // See parseTargetAndFindResolver().
|
||||||
dopts dialOptions
|
authority string // See determineAuthority().
|
||||||
csMgr *connectivityStateManager
|
dopts dialOptions // Default and user specified dial options.
|
||||||
|
channelzID *channelz.Identifier // Channelz identifier for the channel.
|
||||||
balancerBuildOpts balancer.BuildOptions
|
balancerWrapper *ccBalancerWrapper // Uses gracefulswitch.balancer underneath.
|
||||||
blockingpicker *pickerWrapper
|
|
||||||
|
|
||||||
|
// The following provide their own synchronization, and therefore don't
|
||||||
|
// require cc.mu to be held to access them.
|
||||||
|
csMgr *connectivityStateManager
|
||||||
|
blockingpicker *pickerWrapper
|
||||||
safeConfigSelector iresolver.SafeConfigSelector
|
safeConfigSelector iresolver.SafeConfigSelector
|
||||||
|
czData *channelzData
|
||||||
|
retryThrottler atomic.Value // Updated from service config.
|
||||||
|
|
||||||
mu sync.RWMutex
|
// firstResolveEvent is used to track whether the name resolver sent us at
|
||||||
resolverWrapper *ccResolverWrapper
|
// least one update. RPCs block on this event.
|
||||||
sc *ServiceConfig
|
|
||||||
conns map[*addrConn]struct{}
|
|
||||||
// Keepalive parameter can be updated if a GoAway is received.
|
|
||||||
mkp keepalive.ClientParameters
|
|
||||||
curBalancerName string
|
|
||||||
balancerWrapper *ccBalancerWrapper
|
|
||||||
retryThrottler atomic.Value
|
|
||||||
|
|
||||||
firstResolveEvent *grpcsync.Event
|
firstResolveEvent *grpcsync.Event
|
||||||
|
|
||||||
channelzID int64 // channelz unique identification number
|
// mu protects the following fields.
|
||||||
czData *channelzData
|
// TODO: split mu so the same mutex isn't used for everything.
|
||||||
|
mu sync.RWMutex
|
||||||
|
resolverWrapper *ccResolverWrapper // Initialized in Dial; cleared in Close.
|
||||||
|
sc *ServiceConfig // Latest service config received from the resolver.
|
||||||
|
conns map[*addrConn]struct{} // Set to nil on close.
|
||||||
|
mkp keepalive.ClientParameters // May be updated upon receipt of a GoAway.
|
||||||
|
|
||||||
lceMu sync.Mutex // protects lastConnectionError
|
lceMu sync.Mutex // protects lastConnectionError
|
||||||
lastConnectionError error
|
lastConnectionError error
|
||||||
@ -536,14 +535,7 @@ func (cc *ClientConn) GetState() connectivity.State {
|
|||||||
// Notice: This API is EXPERIMENTAL and may be changed or removed in a later
|
// Notice: This API is EXPERIMENTAL and may be changed or removed in a later
|
||||||
// release.
|
// release.
|
||||||
func (cc *ClientConn) Connect() {
|
func (cc *ClientConn) Connect() {
|
||||||
cc.mu.Lock()
|
cc.balancerWrapper.exitIdle()
|
||||||
defer cc.mu.Unlock()
|
|
||||||
if cc.balancerWrapper != nil && cc.balancerWrapper.exitIdle() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for ac := range cc.conns {
|
|
||||||
go ac.connect()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cc *ClientConn) scWatcher() {
|
func (cc *ClientConn) scWatcher() {
|
||||||
@ -623,9 +615,7 @@ func (cc *ClientConn) updateResolverState(s resolver.State, err error) error {
|
|||||||
// with the new addresses.
|
// with the new addresses.
|
||||||
cc.maybeApplyDefaultServiceConfig(nil)
|
cc.maybeApplyDefaultServiceConfig(nil)
|
||||||
|
|
||||||
if cc.balancerWrapper != nil {
|
cc.balancerWrapper.resolverError(err)
|
||||||
cc.balancerWrapper.resolverError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// No addresses are valid with err set; return early.
|
// No addresses are valid with err set; return early.
|
||||||
cc.mu.Unlock()
|
cc.mu.Unlock()
|
||||||
@ -653,16 +643,10 @@ func (cc *ClientConn) updateResolverState(s resolver.State, err error) error {
|
|||||||
cc.applyServiceConfigAndBalancer(sc, configSelector, s.Addresses)
|
cc.applyServiceConfigAndBalancer(sc, configSelector, s.Addresses)
|
||||||
} else {
|
} else {
|
||||||
ret = balancer.ErrBadResolverState
|
ret = balancer.ErrBadResolverState
|
||||||
if cc.balancerWrapper == nil {
|
if cc.sc == nil {
|
||||||
var err error
|
// Apply the failing LB only if we haven't received valid service config
|
||||||
if s.ServiceConfig.Err != nil {
|
// from the name resolver in the past.
|
||||||
err = status.Errorf(codes.Unavailable, "error parsing service config: %v", s.ServiceConfig.Err)
|
cc.applyFailingLB(s.ServiceConfig)
|
||||||
} else {
|
|
||||||
err = status.Errorf(codes.Unavailable, "illegal service config type: %T", s.ServiceConfig.Config)
|
|
||||||
}
|
|
||||||
cc.safeConfigSelector.UpdateConfigSelector(&defaultConfigSelector{cc.sc})
|
|
||||||
cc.blockingpicker.updatePicker(base.NewErrPicker(err))
|
|
||||||
cc.csMgr.updateState(connectivity.TransientFailure)
|
|
||||||
cc.mu.Unlock()
|
cc.mu.Unlock()
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
@ -670,24 +654,12 @@ func (cc *ClientConn) updateResolverState(s resolver.State, err error) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var balCfg serviceconfig.LoadBalancingConfig
|
var balCfg serviceconfig.LoadBalancingConfig
|
||||||
if cc.dopts.balancerBuilder == nil && cc.sc != nil && cc.sc.lbConfig != nil {
|
if cc.sc != nil && cc.sc.lbConfig != nil {
|
||||||
balCfg = cc.sc.lbConfig.cfg
|
balCfg = cc.sc.lbConfig.cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
cbn := cc.curBalancerName
|
|
||||||
bw := cc.balancerWrapper
|
bw := cc.balancerWrapper
|
||||||
cc.mu.Unlock()
|
cc.mu.Unlock()
|
||||||
if cbn != grpclbName {
|
|
||||||
// Filter any grpclb addresses since we don't have the grpclb balancer.
|
|
||||||
for i := 0; i < len(s.Addresses); {
|
|
||||||
if s.Addresses[i].Type == resolver.GRPCLB {
|
|
||||||
copy(s.Addresses[i:], s.Addresses[i+1:])
|
|
||||||
s.Addresses = s.Addresses[:len(s.Addresses)-1]
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
uccsErr := bw.updateClientConnState(&balancer.ClientConnState{ResolverState: s, BalancerConfig: balCfg})
|
uccsErr := bw.updateClientConnState(&balancer.ClientConnState{ResolverState: s, BalancerConfig: balCfg})
|
||||||
if ret == nil {
|
if ret == nil {
|
||||||
ret = uccsErr // prefer ErrBadResolver state since any other error is
|
ret = uccsErr // prefer ErrBadResolver state since any other error is
|
||||||
@ -696,56 +668,28 @@ func (cc *ClientConn) updateResolverState(s resolver.State, err error) error {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
// switchBalancer starts the switching from current balancer to the balancer
|
// applyFailingLB is akin to configuring an LB policy on the channel which
|
||||||
// with the given name.
|
// always fails RPCs. Here, an actual LB policy is not configured, but an always
|
||||||
//
|
// erroring picker is configured, which returns errors with information about
|
||||||
// It will NOT send the current address list to the new balancer. If needed,
|
// what was invalid in the received service config. A config selector with no
|
||||||
// caller of this function should send address list to the new balancer after
|
// service config is configured, and the connectivity state of the channel is
|
||||||
// this function returns.
|
// set to TransientFailure.
|
||||||
//
|
//
|
||||||
// Caller must hold cc.mu.
|
// Caller must hold cc.mu.
|
||||||
func (cc *ClientConn) switchBalancer(name string) {
|
func (cc *ClientConn) applyFailingLB(sc *serviceconfig.ParseResult) {
|
||||||
if strings.EqualFold(cc.curBalancerName, name) {
|
var err error
|
||||||
return
|
if sc.Err != nil {
|
||||||
}
|
err = status.Errorf(codes.Unavailable, "error parsing service config: %v", sc.Err)
|
||||||
|
|
||||||
channelz.Infof(logger, cc.channelzID, "ClientConn switching balancer to %q", name)
|
|
||||||
if cc.dopts.balancerBuilder != nil {
|
|
||||||
channelz.Info(logger, cc.channelzID, "ignoring balancer switching: Balancer DialOption used instead")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if cc.balancerWrapper != nil {
|
|
||||||
// Don't hold cc.mu while closing the balancers. The balancers may call
|
|
||||||
// methods that require cc.mu (e.g. cc.NewSubConn()). Holding the mutex
|
|
||||||
// would cause a deadlock in that case.
|
|
||||||
cc.mu.Unlock()
|
|
||||||
cc.balancerWrapper.close()
|
|
||||||
cc.mu.Lock()
|
|
||||||
}
|
|
||||||
|
|
||||||
builder := balancer.Get(name)
|
|
||||||
if builder == nil {
|
|
||||||
channelz.Warningf(logger, cc.channelzID, "Channel switches to new LB policy %q due to fallback from invalid balancer name", PickFirstBalancerName)
|
|
||||||
channelz.Infof(logger, cc.channelzID, "failed to get balancer builder for: %v, using pick_first instead", name)
|
|
||||||
builder = newPickfirstBuilder()
|
|
||||||
} else {
|
} else {
|
||||||
channelz.Infof(logger, cc.channelzID, "Channel switches to new LB policy %q", name)
|
err = status.Errorf(codes.Unavailable, "illegal service config type: %T", sc.Config)
|
||||||
}
|
}
|
||||||
|
cc.safeConfigSelector.UpdateConfigSelector(&defaultConfigSelector{nil})
|
||||||
cc.curBalancerName = builder.Name()
|
cc.blockingpicker.updatePicker(base.NewErrPicker(err))
|
||||||
cc.balancerWrapper = newCCBalancerWrapper(cc, builder, cc.balancerBuildOpts)
|
cc.csMgr.updateState(connectivity.TransientFailure)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cc *ClientConn) handleSubConnStateChange(sc balancer.SubConn, s connectivity.State, err error) {
|
func (cc *ClientConn) handleSubConnStateChange(sc balancer.SubConn, s connectivity.State, err error) {
|
||||||
cc.mu.Lock()
|
cc.balancerWrapper.updateSubConnState(sc, s, err)
|
||||||
if cc.conns == nil {
|
|
||||||
cc.mu.Unlock()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// TODO(bar switching) send updates to all balancer wrappers when balancer
|
|
||||||
// gracefully switching is supported.
|
|
||||||
cc.balancerWrapper.handleSubConnStateChange(sc, s, err)
|
|
||||||
cc.mu.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// newAddrConn creates an addrConn for addrs and adds it to cc.conns.
|
// newAddrConn creates an addrConn for addrs and adds it to cc.conns.
|
||||||
@ -768,17 +712,21 @@ func (cc *ClientConn) newAddrConn(addrs []resolver.Address, opts balancer.NewSub
|
|||||||
cc.mu.Unlock()
|
cc.mu.Unlock()
|
||||||
return nil, ErrClientConnClosing
|
return nil, ErrClientConnClosing
|
||||||
}
|
}
|
||||||
if channelz.IsOn() {
|
|
||||||
ac.channelzID = channelz.RegisterSubChannel(ac, cc.channelzID, "")
|
var err error
|
||||||
channelz.AddTraceEvent(logger, ac.channelzID, 0, &channelz.TraceEventDesc{
|
ac.channelzID, err = channelz.RegisterSubChannel(ac, cc.channelzID, "")
|
||||||
Desc: "Subchannel Created",
|
if err != nil {
|
||||||
Severity: channelz.CtInfo,
|
return nil, err
|
||||||
Parent: &channelz.TraceEventDesc{
|
|
||||||
Desc: fmt.Sprintf("Subchannel(id:%d) created", ac.channelzID),
|
|
||||||
Severity: channelz.CtInfo,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
channelz.AddTraceEvent(logger, ac.channelzID, 0, &channelz.TraceEventDesc{
|
||||||
|
Desc: "Subchannel created",
|
||||||
|
Severity: channelz.CtInfo,
|
||||||
|
Parent: &channelz.TraceEventDesc{
|
||||||
|
Desc: fmt.Sprintf("Subchannel(id:%d) created", ac.channelzID.Int()),
|
||||||
|
Severity: channelz.CtInfo,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
cc.conns[ac] = struct{}{}
|
cc.conns[ac] = struct{}{}
|
||||||
cc.mu.Unlock()
|
cc.mu.Unlock()
|
||||||
return ac, nil
|
return ac, nil
|
||||||
@ -991,35 +939,26 @@ func (cc *ClientConn) applyServiceConfigAndBalancer(sc *ServiceConfig, configSel
|
|||||||
cc.retryThrottler.Store((*retryThrottler)(nil))
|
cc.retryThrottler.Store((*retryThrottler)(nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
if cc.dopts.balancerBuilder == nil {
|
var newBalancerName string
|
||||||
// Only look at balancer types and switch balancer if balancer dial
|
if cc.sc != nil && cc.sc.lbConfig != nil {
|
||||||
// option is not set.
|
newBalancerName = cc.sc.lbConfig.name
|
||||||
var newBalancerName string
|
} else {
|
||||||
if cc.sc != nil && cc.sc.lbConfig != nil {
|
var isGRPCLB bool
|
||||||
newBalancerName = cc.sc.lbConfig.name
|
for _, a := range addrs {
|
||||||
} else {
|
if a.Type == resolver.GRPCLB {
|
||||||
var isGRPCLB bool
|
isGRPCLB = true
|
||||||
for _, a := range addrs {
|
break
|
||||||
if a.Type == resolver.GRPCLB {
|
|
||||||
isGRPCLB = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if isGRPCLB {
|
|
||||||
newBalancerName = grpclbName
|
|
||||||
} else if cc.sc != nil && cc.sc.LB != nil {
|
|
||||||
newBalancerName = *cc.sc.LB
|
|
||||||
} else {
|
|
||||||
newBalancerName = PickFirstBalancerName
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cc.switchBalancer(newBalancerName)
|
if isGRPCLB {
|
||||||
} else if cc.balancerWrapper == nil {
|
newBalancerName = grpclbName
|
||||||
// Balancer dial option was set, and this is the first time handling
|
} else if cc.sc != nil && cc.sc.LB != nil {
|
||||||
// resolved addresses. Build a balancer with dopts.balancerBuilder.
|
newBalancerName = *cc.sc.LB
|
||||||
cc.curBalancerName = cc.dopts.balancerBuilder.Name()
|
} else {
|
||||||
cc.balancerWrapper = newCCBalancerWrapper(cc, cc.dopts.balancerBuilder, cc.balancerBuildOpts)
|
newBalancerName = PickFirstBalancerName
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
cc.balancerWrapper.switchTo(newBalancerName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cc *ClientConn) resolveNow(o resolver.ResolveNowOptions) {
|
func (cc *ClientConn) resolveNow(o resolver.ResolveNowOptions) {
|
||||||
@ -1070,11 +1009,11 @@ func (cc *ClientConn) Close() error {
|
|||||||
rWrapper := cc.resolverWrapper
|
rWrapper := cc.resolverWrapper
|
||||||
cc.resolverWrapper = nil
|
cc.resolverWrapper = nil
|
||||||
bWrapper := cc.balancerWrapper
|
bWrapper := cc.balancerWrapper
|
||||||
cc.balancerWrapper = nil
|
|
||||||
cc.mu.Unlock()
|
cc.mu.Unlock()
|
||||||
|
|
||||||
|
// The order of closing matters here since the balancer wrapper assumes the
|
||||||
|
// picker is closed before it is closed.
|
||||||
cc.blockingpicker.close()
|
cc.blockingpicker.close()
|
||||||
|
|
||||||
if bWrapper != nil {
|
if bWrapper != nil {
|
||||||
bWrapper.close()
|
bWrapper.close()
|
||||||
}
|
}
|
||||||
@ -1085,22 +1024,22 @@ func (cc *ClientConn) Close() error {
|
|||||||
for ac := range conns {
|
for ac := range conns {
|
||||||
ac.tearDown(ErrClientConnClosing)
|
ac.tearDown(ErrClientConnClosing)
|
||||||
}
|
}
|
||||||
if channelz.IsOn() {
|
ted := &channelz.TraceEventDesc{
|
||||||
ted := &channelz.TraceEventDesc{
|
Desc: "Channel deleted",
|
||||||
Desc: "Channel Deleted",
|
Severity: channelz.CtInfo,
|
||||||
|
}
|
||||||
|
if cc.dopts.channelzParentID != nil {
|
||||||
|
ted.Parent = &channelz.TraceEventDesc{
|
||||||
|
Desc: fmt.Sprintf("Nested channel(id:%d) deleted", cc.channelzID.Int()),
|
||||||
Severity: channelz.CtInfo,
|
Severity: channelz.CtInfo,
|
||||||
}
|
}
|
||||||
if cc.dopts.channelzParentID != 0 {
|
|
||||||
ted.Parent = &channelz.TraceEventDesc{
|
|
||||||
Desc: fmt.Sprintf("Nested channel(id:%d) deleted", cc.channelzID),
|
|
||||||
Severity: channelz.CtInfo,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
channelz.AddTraceEvent(logger, cc.channelzID, 0, ted)
|
|
||||||
// TraceEvent needs to be called before RemoveEntry, as TraceEvent may add trace reference to
|
|
||||||
// the entity being deleted, and thus prevent it from being deleted right away.
|
|
||||||
channelz.RemoveEntry(cc.channelzID)
|
|
||||||
}
|
}
|
||||||
|
channelz.AddTraceEvent(logger, cc.channelzID, 0, ted)
|
||||||
|
// TraceEvent needs to be called before RemoveEntry, as TraceEvent may add
|
||||||
|
// trace reference to the entity being deleted, and thus prevent it from being
|
||||||
|
// deleted right away.
|
||||||
|
channelz.RemoveEntry(cc.channelzID)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1130,7 +1069,7 @@ type addrConn struct {
|
|||||||
backoffIdx int // Needs to be stateful for resetConnectBackoff.
|
backoffIdx int // Needs to be stateful for resetConnectBackoff.
|
||||||
resetBackoff chan struct{}
|
resetBackoff chan struct{}
|
||||||
|
|
||||||
channelzID int64 // channelz unique identification number.
|
channelzID *channelz.Identifier
|
||||||
czData *channelzData
|
czData *channelzData
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1312,14 +1251,12 @@ func (ac *addrConn) createTransport(addr resolver.Address, copts transport.Conne
|
|||||||
|
|
||||||
connectCtx, cancel := context.WithDeadline(ac.ctx, connectDeadline)
|
connectCtx, cancel := context.WithDeadline(ac.ctx, connectDeadline)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
if channelz.IsOn() {
|
copts.ChannelzParentID = ac.channelzID
|
||||||
copts.ChannelzParentID = ac.channelzID
|
|
||||||
}
|
|
||||||
|
|
||||||
newTr, err := transport.NewClientTransport(connectCtx, ac.cc.ctx, addr, copts, func() { prefaceReceived.Fire() }, onGoAway, onClose)
|
newTr, err := transport.NewClientTransport(connectCtx, ac.cc.ctx, addr, copts, func() { prefaceReceived.Fire() }, onGoAway, onClose)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// newTr is either nil, or closed.
|
// newTr is either nil, or closed.
|
||||||
channelz.Warningf(logger, ac.channelzID, "grpc: addrConn.createTransport failed to connect to %v. Err: %v", addr, err)
|
channelz.Warningf(logger, ac.channelzID, "grpc: addrConn.createTransport failed to connect to %s. Err: %v", addr, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1332,7 +1269,7 @@ func (ac *addrConn) createTransport(addr resolver.Address, copts transport.Conne
|
|||||||
newTr.Close(transport.ErrConnClosing)
|
newTr.Close(transport.ErrConnClosing)
|
||||||
if connectCtx.Err() == context.DeadlineExceeded {
|
if connectCtx.Err() == context.DeadlineExceeded {
|
||||||
err := errors.New("failed to receive server preface within timeout")
|
err := errors.New("failed to receive server preface within timeout")
|
||||||
channelz.Warningf(logger, ac.channelzID, "grpc: addrConn.createTransport failed to connect to %v: %v", addr, err)
|
channelz.Warningf(logger, ac.channelzID, "grpc: addrConn.createTransport failed to connect to %s: %v", addr, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -1497,19 +1434,18 @@ func (ac *addrConn) tearDown(err error) {
|
|||||||
curTr.GracefulClose()
|
curTr.GracefulClose()
|
||||||
ac.mu.Lock()
|
ac.mu.Lock()
|
||||||
}
|
}
|
||||||
if channelz.IsOn() {
|
channelz.AddTraceEvent(logger, ac.channelzID, 0, &channelz.TraceEventDesc{
|
||||||
channelz.AddTraceEvent(logger, ac.channelzID, 0, &channelz.TraceEventDesc{
|
Desc: "Subchannel deleted",
|
||||||
Desc: "Subchannel Deleted",
|
Severity: channelz.CtInfo,
|
||||||
|
Parent: &channelz.TraceEventDesc{
|
||||||
|
Desc: fmt.Sprintf("Subchannel(id:%d) deleted", ac.channelzID.Int()),
|
||||||
Severity: channelz.CtInfo,
|
Severity: channelz.CtInfo,
|
||||||
Parent: &channelz.TraceEventDesc{
|
},
|
||||||
Desc: fmt.Sprintf("Subchanel(id:%d) deleted", ac.channelzID),
|
})
|
||||||
Severity: channelz.CtInfo,
|
// TraceEvent needs to be called before RemoveEntry, as TraceEvent may add
|
||||||
},
|
// trace reference to the entity being deleted, and thus prevent it from
|
||||||
})
|
// being deleted right away.
|
||||||
// TraceEvent needs to be called before RemoveEntry, as TraceEvent may add trace reference to
|
channelz.RemoveEntry(ac.channelzID)
|
||||||
// the entity being deleted, and thus prevent it from being deleted right away.
|
|
||||||
channelz.RemoveEntry(ac.channelzID)
|
|
||||||
}
|
|
||||||
ac.mu.Unlock()
|
ac.mu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
52
vendor/google.golang.org/grpc/dialoptions.go
generated
vendored
52
vendor/google.golang.org/grpc/dialoptions.go
generated
vendored
@ -20,12 +20,11 @@ package grpc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"google.golang.org/grpc/backoff"
|
"google.golang.org/grpc/backoff"
|
||||||
"google.golang.org/grpc/balancer"
|
"google.golang.org/grpc/channelz"
|
||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
"google.golang.org/grpc/credentials/insecure"
|
"google.golang.org/grpc/credentials/insecure"
|
||||||
"google.golang.org/grpc/internal"
|
"google.golang.org/grpc/internal"
|
||||||
@ -45,19 +44,17 @@ type dialOptions struct {
|
|||||||
chainUnaryInts []UnaryClientInterceptor
|
chainUnaryInts []UnaryClientInterceptor
|
||||||
chainStreamInts []StreamClientInterceptor
|
chainStreamInts []StreamClientInterceptor
|
||||||
|
|
||||||
cp Compressor
|
cp Compressor
|
||||||
dc Decompressor
|
dc Decompressor
|
||||||
bs internalbackoff.Strategy
|
bs internalbackoff.Strategy
|
||||||
block bool
|
block bool
|
||||||
returnLastError bool
|
returnLastError bool
|
||||||
timeout time.Duration
|
timeout time.Duration
|
||||||
scChan <-chan ServiceConfig
|
scChan <-chan ServiceConfig
|
||||||
authority string
|
authority string
|
||||||
copts transport.ConnectOptions
|
copts transport.ConnectOptions
|
||||||
callOptions []CallOption
|
callOptions []CallOption
|
||||||
// This is used by WithBalancerName dial option.
|
channelzParentID *channelz.Identifier
|
||||||
balancerBuilder balancer.Builder
|
|
||||||
channelzParentID int64
|
|
||||||
disableServiceConfig bool
|
disableServiceConfig bool
|
||||||
disableRetry bool
|
disableRetry bool
|
||||||
disableHealthCheck bool
|
disableHealthCheck bool
|
||||||
@ -195,25 +192,6 @@ func WithDecompressor(dc Decompressor) DialOption {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithBalancerName sets the balancer that the ClientConn will be initialized
|
|
||||||
// with. Balancer registered with balancerName will be used. This function
|
|
||||||
// panics if no balancer was registered by balancerName.
|
|
||||||
//
|
|
||||||
// The balancer cannot be overridden by balancer option specified by service
|
|
||||||
// config.
|
|
||||||
//
|
|
||||||
// Deprecated: use WithDefaultServiceConfig and WithDisableServiceConfig
|
|
||||||
// instead. Will be removed in a future 1.x release.
|
|
||||||
func WithBalancerName(balancerName string) DialOption {
|
|
||||||
builder := balancer.Get(balancerName)
|
|
||||||
if builder == nil {
|
|
||||||
panic(fmt.Sprintf("grpc.WithBalancerName: no balancer is registered for name %v", balancerName))
|
|
||||||
}
|
|
||||||
return newFuncDialOption(func(o *dialOptions) {
|
|
||||||
o.balancerBuilder = builder
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithServiceConfig returns a DialOption which has a channel to read the
|
// WithServiceConfig returns a DialOption which has a channel to read the
|
||||||
// service configuration.
|
// service configuration.
|
||||||
//
|
//
|
||||||
@ -304,8 +282,8 @@ func WithReturnConnectionError() DialOption {
|
|||||||
// WithCredentialsBundle or WithPerRPCCredentials) which require transport
|
// WithCredentialsBundle or WithPerRPCCredentials) which require transport
|
||||||
// security is incompatible and will cause grpc.Dial() to fail.
|
// security is incompatible and will cause grpc.Dial() to fail.
|
||||||
//
|
//
|
||||||
// Deprecated: use WithTransportCredentials and insecure.NewCredentials() instead.
|
// Deprecated: use WithTransportCredentials and insecure.NewCredentials()
|
||||||
// Will be supported throughout 1.x.
|
// instead. Will be supported throughout 1.x.
|
||||||
func WithInsecure() DialOption {
|
func WithInsecure() DialOption {
|
||||||
return newFuncDialOption(func(o *dialOptions) {
|
return newFuncDialOption(func(o *dialOptions) {
|
||||||
o.copts.TransportCredentials = insecure.NewCredentials()
|
o.copts.TransportCredentials = insecure.NewCredentials()
|
||||||
@ -498,7 +476,7 @@ func WithAuthority(a string) DialOption {
|
|||||||
//
|
//
|
||||||
// Notice: This API is EXPERIMENTAL and may be changed or removed in a
|
// Notice: This API is EXPERIMENTAL and may be changed or removed in a
|
||||||
// later release.
|
// later release.
|
||||||
func WithChannelzParentID(id int64) DialOption {
|
func WithChannelzParentID(id *channelz.Identifier) DialOption {
|
||||||
return newFuncDialOption(func(o *dialOptions) {
|
return newFuncDialOption(func(o *dialOptions) {
|
||||||
o.channelzParentID = id
|
o.channelzParentID = id
|
||||||
})
|
})
|
||||||
|
382
vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go
generated
vendored
Normal file
382
vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go
generated
vendored
Normal file
@ -0,0 +1,382 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2022 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 gracefulswitch implements a graceful switch load balancer.
|
||||||
|
package gracefulswitch
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"google.golang.org/grpc/balancer"
|
||||||
|
"google.golang.org/grpc/balancer/base"
|
||||||
|
"google.golang.org/grpc/connectivity"
|
||||||
|
"google.golang.org/grpc/resolver"
|
||||||
|
)
|
||||||
|
|
||||||
|
var errBalancerClosed = errors.New("gracefulSwitchBalancer is closed")
|
||||||
|
var _ balancer.Balancer = (*Balancer)(nil)
|
||||||
|
|
||||||
|
// NewBalancer returns a graceful switch Balancer.
|
||||||
|
func NewBalancer(cc balancer.ClientConn, opts balancer.BuildOptions) *Balancer {
|
||||||
|
return &Balancer{
|
||||||
|
cc: cc,
|
||||||
|
bOpts: opts,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Balancer is a utility to gracefully switch from one balancer to
|
||||||
|
// a new balancer. It implements the balancer.Balancer interface.
|
||||||
|
type Balancer struct {
|
||||||
|
bOpts balancer.BuildOptions
|
||||||
|
cc balancer.ClientConn
|
||||||
|
|
||||||
|
// mu protects the following fields and all fields within balancerCurrent
|
||||||
|
// and balancerPending. mu does not need to be held when calling into the
|
||||||
|
// child balancers, as all calls into these children happen only as a direct
|
||||||
|
// result of a call into the gracefulSwitchBalancer, which are also
|
||||||
|
// guaranteed to be synchronous. There is one exception: an UpdateState call
|
||||||
|
// from a child balancer when current and pending are populated can lead to
|
||||||
|
// calling Close() on the current. To prevent that racing with an
|
||||||
|
// UpdateSubConnState from the channel, we hold currentMu during Close and
|
||||||
|
// UpdateSubConnState calls.
|
||||||
|
mu sync.Mutex
|
||||||
|
balancerCurrent *balancerWrapper
|
||||||
|
balancerPending *balancerWrapper
|
||||||
|
closed bool // set to true when this balancer is closed
|
||||||
|
|
||||||
|
// currentMu must be locked before mu. This mutex guards against this
|
||||||
|
// sequence of events: UpdateSubConnState() called, finds the
|
||||||
|
// balancerCurrent, gives up lock, updateState comes in, causes Close() on
|
||||||
|
// balancerCurrent before the UpdateSubConnState is called on the
|
||||||
|
// balancerCurrent.
|
||||||
|
currentMu sync.Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
// swap swaps out the current lb with the pending lb and updates the ClientConn.
|
||||||
|
// The caller must hold gsb.mu.
|
||||||
|
func (gsb *Balancer) swap() {
|
||||||
|
gsb.cc.UpdateState(gsb.balancerPending.lastState)
|
||||||
|
cur := gsb.balancerCurrent
|
||||||
|
gsb.balancerCurrent = gsb.balancerPending
|
||||||
|
gsb.balancerPending = nil
|
||||||
|
go func() {
|
||||||
|
gsb.currentMu.Lock()
|
||||||
|
defer gsb.currentMu.Unlock()
|
||||||
|
cur.Close()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function that checks if the balancer passed in is current or pending.
|
||||||
|
// The caller must hold gsb.mu.
|
||||||
|
func (gsb *Balancer) balancerCurrentOrPending(bw *balancerWrapper) bool {
|
||||||
|
return bw == gsb.balancerCurrent || bw == gsb.balancerPending
|
||||||
|
}
|
||||||
|
|
||||||
|
// SwitchTo initializes the graceful switch process, which completes based on
|
||||||
|
// connectivity state changes on the current/pending balancer. Thus, the switch
|
||||||
|
// process is not complete when this method returns. This method must be called
|
||||||
|
// synchronously alongside the rest of the balancer.Balancer methods this
|
||||||
|
// Graceful Switch Balancer implements.
|
||||||
|
func (gsb *Balancer) SwitchTo(builder balancer.Builder) error {
|
||||||
|
gsb.mu.Lock()
|
||||||
|
if gsb.closed {
|
||||||
|
gsb.mu.Unlock()
|
||||||
|
return errBalancerClosed
|
||||||
|
}
|
||||||
|
bw := &balancerWrapper{
|
||||||
|
gsb: gsb,
|
||||||
|
lastState: balancer.State{
|
||||||
|
ConnectivityState: connectivity.Connecting,
|
||||||
|
Picker: base.NewErrPicker(balancer.ErrNoSubConnAvailable),
|
||||||
|
},
|
||||||
|
subconns: make(map[balancer.SubConn]bool),
|
||||||
|
}
|
||||||
|
balToClose := gsb.balancerPending // nil if there is no pending balancer
|
||||||
|
if gsb.balancerCurrent == nil {
|
||||||
|
gsb.balancerCurrent = bw
|
||||||
|
} else {
|
||||||
|
gsb.balancerPending = bw
|
||||||
|
}
|
||||||
|
gsb.mu.Unlock()
|
||||||
|
balToClose.Close()
|
||||||
|
// This function takes a builder instead of a balancer because builder.Build
|
||||||
|
// can call back inline, and this utility needs to handle the callbacks.
|
||||||
|
newBalancer := builder.Build(bw, gsb.bOpts)
|
||||||
|
if newBalancer == nil {
|
||||||
|
// This is illegal and should never happen; we clear the balancerWrapper
|
||||||
|
// we were constructing if it happens to avoid a potential panic.
|
||||||
|
gsb.mu.Lock()
|
||||||
|
if gsb.balancerPending != nil {
|
||||||
|
gsb.balancerPending = nil
|
||||||
|
} else {
|
||||||
|
gsb.balancerCurrent = nil
|
||||||
|
}
|
||||||
|
gsb.mu.Unlock()
|
||||||
|
return balancer.ErrBadResolverState
|
||||||
|
}
|
||||||
|
|
||||||
|
// This write doesn't need to take gsb.mu because this field never gets read
|
||||||
|
// or written to on any calls from the current or pending. Calls from grpc
|
||||||
|
// to this balancer are guaranteed to be called synchronously, so this
|
||||||
|
// bw.Balancer field will never be forwarded to until this SwitchTo()
|
||||||
|
// function returns.
|
||||||
|
bw.Balancer = newBalancer
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns nil if the graceful switch balancer is closed.
|
||||||
|
func (gsb *Balancer) latestBalancer() *balancerWrapper {
|
||||||
|
gsb.mu.Lock()
|
||||||
|
defer gsb.mu.Unlock()
|
||||||
|
if gsb.balancerPending != nil {
|
||||||
|
return gsb.balancerPending
|
||||||
|
}
|
||||||
|
return gsb.balancerCurrent
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateClientConnState forwards the update to the latest balancer created.
|
||||||
|
func (gsb *Balancer) UpdateClientConnState(state balancer.ClientConnState) error {
|
||||||
|
// The resolver data is only relevant to the most recent LB Policy.
|
||||||
|
balToUpdate := gsb.latestBalancer()
|
||||||
|
if balToUpdate == nil {
|
||||||
|
return errBalancerClosed
|
||||||
|
}
|
||||||
|
// Perform this call without gsb.mu to prevent deadlocks if the child calls
|
||||||
|
// back into the channel. The latest balancer can never be closed during a
|
||||||
|
// call from the channel, even without gsb.mu held.
|
||||||
|
return balToUpdate.UpdateClientConnState(state)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResolverError forwards the error to the latest balancer created.
|
||||||
|
func (gsb *Balancer) ResolverError(err error) {
|
||||||
|
// The resolver data is only relevant to the most recent LB Policy.
|
||||||
|
balToUpdate := gsb.latestBalancer()
|
||||||
|
if balToUpdate == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Perform this call without gsb.mu to prevent deadlocks if the child calls
|
||||||
|
// back into the channel. The latest balancer can never be closed during a
|
||||||
|
// call from the channel, even without gsb.mu held.
|
||||||
|
balToUpdate.ResolverError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExitIdle forwards the call to the latest balancer created.
|
||||||
|
//
|
||||||
|
// If the latest balancer does not support ExitIdle, the subConns are
|
||||||
|
// re-connected to manually.
|
||||||
|
func (gsb *Balancer) ExitIdle() {
|
||||||
|
balToUpdate := gsb.latestBalancer()
|
||||||
|
if balToUpdate == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// There is no need to protect this read with a mutex, as the write to the
|
||||||
|
// Balancer field happens in SwitchTo, which completes before this can be
|
||||||
|
// called.
|
||||||
|
if ei, ok := balToUpdate.Balancer.(balancer.ExitIdler); ok {
|
||||||
|
ei.ExitIdle()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for sc := range balToUpdate.subconns {
|
||||||
|
sc.Connect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateSubConnState forwards the update to the appropriate child.
|
||||||
|
func (gsb *Balancer) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) {
|
||||||
|
gsb.currentMu.Lock()
|
||||||
|
defer gsb.currentMu.Unlock()
|
||||||
|
gsb.mu.Lock()
|
||||||
|
// Forward update to the appropriate child. Even if there is a pending
|
||||||
|
// balancer, the current balancer should continue to get SubConn updates to
|
||||||
|
// maintain the proper state while the pending is still connecting.
|
||||||
|
var balToUpdate *balancerWrapper
|
||||||
|
if gsb.balancerCurrent != nil && gsb.balancerCurrent.subconns[sc] {
|
||||||
|
balToUpdate = gsb.balancerCurrent
|
||||||
|
} else if gsb.balancerPending != nil && gsb.balancerPending.subconns[sc] {
|
||||||
|
balToUpdate = gsb.balancerPending
|
||||||
|
}
|
||||||
|
gsb.mu.Unlock()
|
||||||
|
if balToUpdate == nil {
|
||||||
|
// SubConn belonged to a stale lb policy that has not yet fully closed,
|
||||||
|
// or the balancer was already closed.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
balToUpdate.UpdateSubConnState(sc, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close closes any active child balancers.
|
||||||
|
func (gsb *Balancer) Close() {
|
||||||
|
gsb.mu.Lock()
|
||||||
|
gsb.closed = true
|
||||||
|
currentBalancerToClose := gsb.balancerCurrent
|
||||||
|
gsb.balancerCurrent = nil
|
||||||
|
pendingBalancerToClose := gsb.balancerPending
|
||||||
|
gsb.balancerPending = nil
|
||||||
|
gsb.mu.Unlock()
|
||||||
|
|
||||||
|
currentBalancerToClose.Close()
|
||||||
|
pendingBalancerToClose.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
// balancerWrapper wraps a balancer.Balancer, and overrides some Balancer
|
||||||
|
// methods to help cleanup SubConns created by the wrapped balancer.
|
||||||
|
//
|
||||||
|
// It implements the balancer.ClientConn interface and is passed down in that
|
||||||
|
// capacity to the wrapped balancer. It maintains a set of subConns created by
|
||||||
|
// the wrapped balancer and calls from the latter to create/update/remove
|
||||||
|
// SubConns update this set before being forwarded to the parent ClientConn.
|
||||||
|
// State updates from the wrapped balancer can result in invocation of the
|
||||||
|
// graceful switch logic.
|
||||||
|
type balancerWrapper struct {
|
||||||
|
balancer.Balancer
|
||||||
|
gsb *Balancer
|
||||||
|
|
||||||
|
lastState balancer.State
|
||||||
|
subconns map[balancer.SubConn]bool // subconns created by this balancer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bw *balancerWrapper) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) {
|
||||||
|
if state.ConnectivityState == connectivity.Shutdown {
|
||||||
|
bw.gsb.mu.Lock()
|
||||||
|
delete(bw.subconns, sc)
|
||||||
|
bw.gsb.mu.Unlock()
|
||||||
|
}
|
||||||
|
// There is no need to protect this read with a mutex, as the write to the
|
||||||
|
// Balancer field happens in SwitchTo, which completes before this can be
|
||||||
|
// called.
|
||||||
|
bw.Balancer.UpdateSubConnState(sc, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close closes the underlying LB policy and removes the subconns it created. bw
|
||||||
|
// must not be referenced via balancerCurrent or balancerPending in gsb when
|
||||||
|
// called. gsb.mu must not be held. Does not panic with a nil receiver.
|
||||||
|
func (bw *balancerWrapper) Close() {
|
||||||
|
// before Close is called.
|
||||||
|
if bw == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// There is no need to protect this read with a mutex, as Close() is
|
||||||
|
// impossible to be called concurrently with the write in SwitchTo(). The
|
||||||
|
// callsites of Close() for this balancer in Graceful Switch Balancer will
|
||||||
|
// never be called until SwitchTo() returns.
|
||||||
|
bw.Balancer.Close()
|
||||||
|
bw.gsb.mu.Lock()
|
||||||
|
for sc := range bw.subconns {
|
||||||
|
bw.gsb.cc.RemoveSubConn(sc)
|
||||||
|
}
|
||||||
|
bw.gsb.mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bw *balancerWrapper) UpdateState(state balancer.State) {
|
||||||
|
// Hold the mutex for this entire call to ensure it cannot occur
|
||||||
|
// concurrently with other updateState() calls. This causes updates to
|
||||||
|
// lastState and calls to cc.UpdateState to happen atomically.
|
||||||
|
bw.gsb.mu.Lock()
|
||||||
|
defer bw.gsb.mu.Unlock()
|
||||||
|
bw.lastState = state
|
||||||
|
|
||||||
|
if !bw.gsb.balancerCurrentOrPending(bw) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if bw == bw.gsb.balancerCurrent {
|
||||||
|
// In the case that the current balancer exits READY, and there is a pending
|
||||||
|
// balancer, you can forward the pending balancer's cached State up to
|
||||||
|
// ClientConn and swap the pending into the current. This is because there
|
||||||
|
// is no reason to gracefully switch from and keep using the old policy as
|
||||||
|
// the ClientConn is not connected to any backends.
|
||||||
|
if state.ConnectivityState != connectivity.Ready && bw.gsb.balancerPending != nil {
|
||||||
|
bw.gsb.swap()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Even if there is a pending balancer waiting to be gracefully switched to,
|
||||||
|
// continue to forward current balancer updates to the Client Conn. Ignoring
|
||||||
|
// state + picker from the current would cause undefined behavior/cause the
|
||||||
|
// system to behave incorrectly from the current LB policies perspective.
|
||||||
|
// Also, the current LB is still being used by grpc to choose SubConns per
|
||||||
|
// RPC, and thus should use the most updated form of the current balancer.
|
||||||
|
bw.gsb.cc.UpdateState(state)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// This method is now dealing with a state update from the pending balancer.
|
||||||
|
// If the current balancer is currently in a state other than READY, the new
|
||||||
|
// policy can be swapped into place immediately. This is because there is no
|
||||||
|
// reason to gracefully switch from and keep using the old policy as the
|
||||||
|
// ClientConn is not connected to any backends.
|
||||||
|
if state.ConnectivityState != connectivity.Connecting || bw.gsb.balancerCurrent.lastState.ConnectivityState != connectivity.Ready {
|
||||||
|
bw.gsb.swap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bw *balancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) {
|
||||||
|
bw.gsb.mu.Lock()
|
||||||
|
if !bw.gsb.balancerCurrentOrPending(bw) {
|
||||||
|
bw.gsb.mu.Unlock()
|
||||||
|
return nil, fmt.Errorf("%T at address %p that called NewSubConn is deleted", bw, bw)
|
||||||
|
}
|
||||||
|
bw.gsb.mu.Unlock()
|
||||||
|
|
||||||
|
sc, err := bw.gsb.cc.NewSubConn(addrs, opts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
bw.gsb.mu.Lock()
|
||||||
|
if !bw.gsb.balancerCurrentOrPending(bw) { // balancer was closed during this call
|
||||||
|
bw.gsb.cc.RemoveSubConn(sc)
|
||||||
|
bw.gsb.mu.Unlock()
|
||||||
|
return nil, fmt.Errorf("%T at address %p that called NewSubConn is deleted", bw, bw)
|
||||||
|
}
|
||||||
|
bw.subconns[sc] = true
|
||||||
|
bw.gsb.mu.Unlock()
|
||||||
|
return sc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bw *balancerWrapper) ResolveNow(opts resolver.ResolveNowOptions) {
|
||||||
|
// Ignore ResolveNow requests from anything other than the most recent
|
||||||
|
// balancer, because older balancers were already removed from the config.
|
||||||
|
if bw != bw.gsb.latestBalancer() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
bw.gsb.cc.ResolveNow(opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bw *balancerWrapper) RemoveSubConn(sc balancer.SubConn) {
|
||||||
|
bw.gsb.mu.Lock()
|
||||||
|
if !bw.gsb.balancerCurrentOrPending(bw) {
|
||||||
|
bw.gsb.mu.Unlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
bw.gsb.mu.Unlock()
|
||||||
|
bw.gsb.cc.RemoveSubConn(sc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bw *balancerWrapper) UpdateAddresses(sc balancer.SubConn, addrs []resolver.Address) {
|
||||||
|
bw.gsb.mu.Lock()
|
||||||
|
if !bw.gsb.balancerCurrentOrPending(bw) {
|
||||||
|
bw.gsb.mu.Unlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
bw.gsb.mu.Unlock()
|
||||||
|
bw.gsb.cc.UpdateAddresses(sc, addrs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bw *balancerWrapper) Target() string {
|
||||||
|
return bw.gsb.cc.Target()
|
||||||
|
}
|
91
vendor/google.golang.org/grpc/internal/binarylog/binarylog.go
generated
vendored
91
vendor/google.golang.org/grpc/internal/binarylog/binarylog.go
generated
vendored
@ -31,7 +31,7 @@ import (
|
|||||||
// Logger is the global binary logger. It can be used to get binary logger for
|
// Logger is the global binary logger. It can be used to get binary logger for
|
||||||
// each method.
|
// each method.
|
||||||
type Logger interface {
|
type Logger interface {
|
||||||
getMethodLogger(methodName string) *MethodLogger
|
GetMethodLogger(methodName string) MethodLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
// binLogger is the global binary logger for the binary. One of this should be
|
// binLogger is the global binary logger for the binary. One of this should be
|
||||||
@ -49,17 +49,24 @@ func SetLogger(l Logger) {
|
|||||||
binLogger = l
|
binLogger = l
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetLogger gets the binarg logger.
|
||||||
|
//
|
||||||
|
// Only call this at init time.
|
||||||
|
func GetLogger() Logger {
|
||||||
|
return binLogger
|
||||||
|
}
|
||||||
|
|
||||||
// GetMethodLogger returns the methodLogger for the given methodName.
|
// GetMethodLogger returns the methodLogger for the given methodName.
|
||||||
//
|
//
|
||||||
// methodName should be in the format of "/service/method".
|
// methodName should be in the format of "/service/method".
|
||||||
//
|
//
|
||||||
// Each methodLogger returned by this method is a new instance. This is to
|
// Each methodLogger returned by this method is a new instance. This is to
|
||||||
// generate sequence id within the call.
|
// generate sequence id within the call.
|
||||||
func GetMethodLogger(methodName string) *MethodLogger {
|
func GetMethodLogger(methodName string) MethodLogger {
|
||||||
if binLogger == nil {
|
if binLogger == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return binLogger.getMethodLogger(methodName)
|
return binLogger.GetMethodLogger(methodName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -68,17 +75,29 @@ func init() {
|
|||||||
binLogger = NewLoggerFromConfigString(configStr)
|
binLogger = NewLoggerFromConfigString(configStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
type methodLoggerConfig struct {
|
// MethodLoggerConfig contains the setting for logging behavior of a method
|
||||||
|
// logger. Currently, it contains the max length of header and message.
|
||||||
|
type MethodLoggerConfig struct {
|
||||||
// Max length of header and message.
|
// Max length of header and message.
|
||||||
hdr, msg uint64
|
Header, Message uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoggerConfig contains the config for loggers to create method loggers.
|
||||||
|
type LoggerConfig struct {
|
||||||
|
All *MethodLoggerConfig
|
||||||
|
Services map[string]*MethodLoggerConfig
|
||||||
|
Methods map[string]*MethodLoggerConfig
|
||||||
|
|
||||||
|
Blacklist map[string]struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type logger struct {
|
type logger struct {
|
||||||
all *methodLoggerConfig
|
config LoggerConfig
|
||||||
services map[string]*methodLoggerConfig
|
}
|
||||||
methods map[string]*methodLoggerConfig
|
|
||||||
|
|
||||||
blacklist map[string]struct{}
|
// NewLoggerFromConfig builds a logger with the given LoggerConfig.
|
||||||
|
func NewLoggerFromConfig(config LoggerConfig) Logger {
|
||||||
|
return &logger{config: config}
|
||||||
}
|
}
|
||||||
|
|
||||||
// newEmptyLogger creates an empty logger. The map fields need to be filled in
|
// newEmptyLogger creates an empty logger. The map fields need to be filled in
|
||||||
@ -88,57 +107,57 @@ func newEmptyLogger() *logger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set method logger for "*".
|
// Set method logger for "*".
|
||||||
func (l *logger) setDefaultMethodLogger(ml *methodLoggerConfig) error {
|
func (l *logger) setDefaultMethodLogger(ml *MethodLoggerConfig) error {
|
||||||
if l.all != nil {
|
if l.config.All != nil {
|
||||||
return fmt.Errorf("conflicting global rules found")
|
return fmt.Errorf("conflicting global rules found")
|
||||||
}
|
}
|
||||||
l.all = ml
|
l.config.All = ml
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set method logger for "service/*".
|
// Set method logger for "service/*".
|
||||||
//
|
//
|
||||||
// New methodLogger with same service overrides the old one.
|
// New methodLogger with same service overrides the old one.
|
||||||
func (l *logger) setServiceMethodLogger(service string, ml *methodLoggerConfig) error {
|
func (l *logger) setServiceMethodLogger(service string, ml *MethodLoggerConfig) error {
|
||||||
if _, ok := l.services[service]; ok {
|
if _, ok := l.config.Services[service]; ok {
|
||||||
return fmt.Errorf("conflicting service rules for service %v found", service)
|
return fmt.Errorf("conflicting service rules for service %v found", service)
|
||||||
}
|
}
|
||||||
if l.services == nil {
|
if l.config.Services == nil {
|
||||||
l.services = make(map[string]*methodLoggerConfig)
|
l.config.Services = make(map[string]*MethodLoggerConfig)
|
||||||
}
|
}
|
||||||
l.services[service] = ml
|
l.config.Services[service] = ml
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set method logger for "service/method".
|
// Set method logger for "service/method".
|
||||||
//
|
//
|
||||||
// New methodLogger with same method overrides the old one.
|
// New methodLogger with same method overrides the old one.
|
||||||
func (l *logger) setMethodMethodLogger(method string, ml *methodLoggerConfig) error {
|
func (l *logger) setMethodMethodLogger(method string, ml *MethodLoggerConfig) error {
|
||||||
if _, ok := l.blacklist[method]; ok {
|
if _, ok := l.config.Blacklist[method]; ok {
|
||||||
return fmt.Errorf("conflicting blacklist rules for method %v found", method)
|
return fmt.Errorf("conflicting blacklist rules for method %v found", method)
|
||||||
}
|
}
|
||||||
if _, ok := l.methods[method]; ok {
|
if _, ok := l.config.Methods[method]; ok {
|
||||||
return fmt.Errorf("conflicting method rules for method %v found", method)
|
return fmt.Errorf("conflicting method rules for method %v found", method)
|
||||||
}
|
}
|
||||||
if l.methods == nil {
|
if l.config.Methods == nil {
|
||||||
l.methods = make(map[string]*methodLoggerConfig)
|
l.config.Methods = make(map[string]*MethodLoggerConfig)
|
||||||
}
|
}
|
||||||
l.methods[method] = ml
|
l.config.Methods[method] = ml
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set blacklist method for "-service/method".
|
// Set blacklist method for "-service/method".
|
||||||
func (l *logger) setBlacklist(method string) error {
|
func (l *logger) setBlacklist(method string) error {
|
||||||
if _, ok := l.blacklist[method]; ok {
|
if _, ok := l.config.Blacklist[method]; ok {
|
||||||
return fmt.Errorf("conflicting blacklist rules for method %v found", method)
|
return fmt.Errorf("conflicting blacklist rules for method %v found", method)
|
||||||
}
|
}
|
||||||
if _, ok := l.methods[method]; ok {
|
if _, ok := l.config.Methods[method]; ok {
|
||||||
return fmt.Errorf("conflicting method rules for method %v found", method)
|
return fmt.Errorf("conflicting method rules for method %v found", method)
|
||||||
}
|
}
|
||||||
if l.blacklist == nil {
|
if l.config.Blacklist == nil {
|
||||||
l.blacklist = make(map[string]struct{})
|
l.config.Blacklist = make(map[string]struct{})
|
||||||
}
|
}
|
||||||
l.blacklist[method] = struct{}{}
|
l.config.Blacklist[method] = struct{}{}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,23 +167,23 @@ func (l *logger) setBlacklist(method string) error {
|
|||||||
//
|
//
|
||||||
// Each methodLogger returned by this method is a new instance. This is to
|
// Each methodLogger returned by this method is a new instance. This is to
|
||||||
// generate sequence id within the call.
|
// generate sequence id within the call.
|
||||||
func (l *logger) getMethodLogger(methodName string) *MethodLogger {
|
func (l *logger) GetMethodLogger(methodName string) MethodLogger {
|
||||||
s, m, err := grpcutil.ParseMethod(methodName)
|
s, m, err := grpcutil.ParseMethod(methodName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
grpclogLogger.Infof("binarylogging: failed to parse %q: %v", methodName, err)
|
grpclogLogger.Infof("binarylogging: failed to parse %q: %v", methodName, err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if ml, ok := l.methods[s+"/"+m]; ok {
|
if ml, ok := l.config.Methods[s+"/"+m]; ok {
|
||||||
return newMethodLogger(ml.hdr, ml.msg)
|
return newMethodLogger(ml.Header, ml.Message)
|
||||||
}
|
}
|
||||||
if _, ok := l.blacklist[s+"/"+m]; ok {
|
if _, ok := l.config.Blacklist[s+"/"+m]; ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if ml, ok := l.services[s]; ok {
|
if ml, ok := l.config.Services[s]; ok {
|
||||||
return newMethodLogger(ml.hdr, ml.msg)
|
return newMethodLogger(ml.Header, ml.Message)
|
||||||
}
|
}
|
||||||
if l.all == nil {
|
if l.config.All == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return newMethodLogger(l.all.hdr, l.all.msg)
|
return newMethodLogger(l.config.All.Header, l.config.All.Message)
|
||||||
}
|
}
|
||||||
|
6
vendor/google.golang.org/grpc/internal/binarylog/env_config.go
generated
vendored
6
vendor/google.golang.org/grpc/internal/binarylog/env_config.go
generated
vendored
@ -89,7 +89,7 @@ func (l *logger) fillMethodLoggerWithConfigString(config string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid config: %q, %v", config, err)
|
return fmt.Errorf("invalid config: %q, %v", config, err)
|
||||||
}
|
}
|
||||||
if err := l.setDefaultMethodLogger(&methodLoggerConfig{hdr: hdr, msg: msg}); err != nil {
|
if err := l.setDefaultMethodLogger(&MethodLoggerConfig{Header: hdr, Message: msg}); err != nil {
|
||||||
return fmt.Errorf("invalid config: %v", err)
|
return fmt.Errorf("invalid config: %v", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -104,11 +104,11 @@ func (l *logger) fillMethodLoggerWithConfigString(config string) error {
|
|||||||
return fmt.Errorf("invalid header/message length config: %q, %v", suffix, err)
|
return fmt.Errorf("invalid header/message length config: %q, %v", suffix, err)
|
||||||
}
|
}
|
||||||
if m == "*" {
|
if m == "*" {
|
||||||
if err := l.setServiceMethodLogger(s, &methodLoggerConfig{hdr: hdr, msg: msg}); err != nil {
|
if err := l.setServiceMethodLogger(s, &MethodLoggerConfig{Header: hdr, Message: msg}); err != nil {
|
||||||
return fmt.Errorf("invalid config: %v", err)
|
return fmt.Errorf("invalid config: %v", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if err := l.setMethodMethodLogger(s+"/"+m, &methodLoggerConfig{hdr: hdr, msg: msg}); err != nil {
|
if err := l.setMethodMethodLogger(s+"/"+m, &MethodLoggerConfig{Header: hdr, Message: msg}); err != nil {
|
||||||
return fmt.Errorf("invalid config: %v", err)
|
return fmt.Errorf("invalid config: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
28
vendor/google.golang.org/grpc/internal/binarylog/method_logger.go
generated
vendored
28
vendor/google.golang.org/grpc/internal/binarylog/method_logger.go
generated
vendored
@ -48,7 +48,11 @@ func (g *callIDGenerator) reset() {
|
|||||||
var idGen callIDGenerator
|
var idGen callIDGenerator
|
||||||
|
|
||||||
// MethodLogger is the sub-logger for each method.
|
// MethodLogger is the sub-logger for each method.
|
||||||
type MethodLogger struct {
|
type MethodLogger interface {
|
||||||
|
Log(LogEntryConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
type methodLogger struct {
|
||||||
headerMaxLen, messageMaxLen uint64
|
headerMaxLen, messageMaxLen uint64
|
||||||
|
|
||||||
callID uint64
|
callID uint64
|
||||||
@ -57,8 +61,8 @@ type MethodLogger struct {
|
|||||||
sink Sink // TODO(blog): make this plugable.
|
sink Sink // TODO(blog): make this plugable.
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMethodLogger(h, m uint64) *MethodLogger {
|
func newMethodLogger(h, m uint64) *methodLogger {
|
||||||
return &MethodLogger{
|
return &methodLogger{
|
||||||
headerMaxLen: h,
|
headerMaxLen: h,
|
||||||
messageMaxLen: m,
|
messageMaxLen: m,
|
||||||
|
|
||||||
@ -69,8 +73,10 @@ func newMethodLogger(h, m uint64) *MethodLogger {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log creates a proto binary log entry, and logs it to the sink.
|
// Build is an internal only method for building the proto message out of the
|
||||||
func (ml *MethodLogger) Log(c LogEntryConfig) {
|
// input event. It's made public to enable other library to reuse as much logic
|
||||||
|
// in methodLogger as possible.
|
||||||
|
func (ml *methodLogger) Build(c LogEntryConfig) *pb.GrpcLogEntry {
|
||||||
m := c.toProto()
|
m := c.toProto()
|
||||||
timestamp, _ := ptypes.TimestampProto(time.Now())
|
timestamp, _ := ptypes.TimestampProto(time.Now())
|
||||||
m.Timestamp = timestamp
|
m.Timestamp = timestamp
|
||||||
@ -85,11 +91,15 @@ func (ml *MethodLogger) Log(c LogEntryConfig) {
|
|||||||
case *pb.GrpcLogEntry_Message:
|
case *pb.GrpcLogEntry_Message:
|
||||||
m.PayloadTruncated = ml.truncateMessage(pay.Message)
|
m.PayloadTruncated = ml.truncateMessage(pay.Message)
|
||||||
}
|
}
|
||||||
|
return m
|
||||||
ml.sink.Write(m)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ml *MethodLogger) truncateMetadata(mdPb *pb.Metadata) (truncated bool) {
|
// Log creates a proto binary log entry, and logs it to the sink.
|
||||||
|
func (ml *methodLogger) Log(c LogEntryConfig) {
|
||||||
|
ml.sink.Write(ml.Build(c))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ml *methodLogger) truncateMetadata(mdPb *pb.Metadata) (truncated bool) {
|
||||||
if ml.headerMaxLen == maxUInt {
|
if ml.headerMaxLen == maxUInt {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -119,7 +129,7 @@ func (ml *MethodLogger) truncateMetadata(mdPb *pb.Metadata) (truncated bool) {
|
|||||||
return truncated
|
return truncated
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ml *MethodLogger) truncateMessage(msgPb *pb.Message) (truncated bool) {
|
func (ml *methodLogger) truncateMessage(msgPb *pb.Message) (truncated bool) {
|
||||||
if ml.messageMaxLen == maxUInt {
|
if ml.messageMaxLen == maxUInt {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
159
vendor/google.golang.org/grpc/internal/channelz/funcs.go
generated
vendored
159
vendor/google.golang.org/grpc/internal/channelz/funcs.go
generated
vendored
@ -25,6 +25,7 @@ package channelz
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
@ -184,54 +185,77 @@ func GetServer(id int64) *ServerMetric {
|
|||||||
return db.get().GetServer(id)
|
return db.get().GetServer(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterChannel registers the given channel c in channelz database with ref
|
// RegisterChannel registers the given channel c in the channelz database with
|
||||||
// as its reference name, and add it to the child list of its parent (identified
|
// ref as its reference name, and adds it to the child list of its parent
|
||||||
// by pid). pid = 0 means no parent. It returns the unique channelz tracking id
|
// (identified by pid). pid == nil means no parent.
|
||||||
// assigned to this channel.
|
//
|
||||||
func RegisterChannel(c Channel, pid int64, ref string) int64 {
|
// Returns a unique channelz identifier assigned to this channel.
|
||||||
|
//
|
||||||
|
// If channelz is not turned ON, the channelz database is not mutated.
|
||||||
|
func RegisterChannel(c Channel, pid *Identifier, ref string) *Identifier {
|
||||||
id := idGen.genID()
|
id := idGen.genID()
|
||||||
|
var parent int64
|
||||||
|
isTopChannel := true
|
||||||
|
if pid != nil {
|
||||||
|
isTopChannel = false
|
||||||
|
parent = pid.Int()
|
||||||
|
}
|
||||||
|
|
||||||
|
if !IsOn() {
|
||||||
|
return newIdentifer(RefChannel, id, pid)
|
||||||
|
}
|
||||||
|
|
||||||
cn := &channel{
|
cn := &channel{
|
||||||
refName: ref,
|
refName: ref,
|
||||||
c: c,
|
c: c,
|
||||||
subChans: make(map[int64]string),
|
subChans: make(map[int64]string),
|
||||||
nestedChans: make(map[int64]string),
|
nestedChans: make(map[int64]string),
|
||||||
id: id,
|
id: id,
|
||||||
pid: pid,
|
pid: parent,
|
||||||
trace: &channelTrace{createdTime: time.Now(), events: make([]*TraceEvent, 0, getMaxTraceEntry())},
|
trace: &channelTrace{createdTime: time.Now(), events: make([]*TraceEvent, 0, getMaxTraceEntry())},
|
||||||
}
|
}
|
||||||
if pid == 0 {
|
db.get().addChannel(id, cn, isTopChannel, parent)
|
||||||
db.get().addChannel(id, cn, true, pid)
|
return newIdentifer(RefChannel, id, pid)
|
||||||
} else {
|
|
||||||
db.get().addChannel(id, cn, false, pid)
|
|
||||||
}
|
|
||||||
return id
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterSubChannel registers the given channel c in channelz database with ref
|
// RegisterSubChannel registers the given subChannel c in the channelz database
|
||||||
// as its reference name, and add it to the child list of its parent (identified
|
// with ref as its reference name, and adds it to the child list of its parent
|
||||||
// by pid). It returns the unique channelz tracking id assigned to this subchannel.
|
// (identified by pid).
|
||||||
func RegisterSubChannel(c Channel, pid int64, ref string) int64 {
|
//
|
||||||
if pid == 0 {
|
// Returns a unique channelz identifier assigned to this subChannel.
|
||||||
logger.Error("a SubChannel's parent id cannot be 0")
|
//
|
||||||
return 0
|
// If channelz is not turned ON, the channelz database is not mutated.
|
||||||
|
func RegisterSubChannel(c Channel, pid *Identifier, ref string) (*Identifier, error) {
|
||||||
|
if pid == nil {
|
||||||
|
return nil, errors.New("a SubChannel's parent id cannot be nil")
|
||||||
}
|
}
|
||||||
id := idGen.genID()
|
id := idGen.genID()
|
||||||
|
if !IsOn() {
|
||||||
|
return newIdentifer(RefSubChannel, id, pid), nil
|
||||||
|
}
|
||||||
|
|
||||||
sc := &subChannel{
|
sc := &subChannel{
|
||||||
refName: ref,
|
refName: ref,
|
||||||
c: c,
|
c: c,
|
||||||
sockets: make(map[int64]string),
|
sockets: make(map[int64]string),
|
||||||
id: id,
|
id: id,
|
||||||
pid: pid,
|
pid: pid.Int(),
|
||||||
trace: &channelTrace{createdTime: time.Now(), events: make([]*TraceEvent, 0, getMaxTraceEntry())},
|
trace: &channelTrace{createdTime: time.Now(), events: make([]*TraceEvent, 0, getMaxTraceEntry())},
|
||||||
}
|
}
|
||||||
db.get().addSubChannel(id, sc, pid)
|
db.get().addSubChannel(id, sc, pid.Int())
|
||||||
return id
|
return newIdentifer(RefSubChannel, id, pid), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterServer registers the given server s in channelz database. It returns
|
// RegisterServer registers the given server s in channelz database. It returns
|
||||||
// the unique channelz tracking id assigned to this server.
|
// the unique channelz tracking id assigned to this server.
|
||||||
func RegisterServer(s Server, ref string) int64 {
|
//
|
||||||
|
// If channelz is not turned ON, the channelz database is not mutated.
|
||||||
|
func RegisterServer(s Server, ref string) *Identifier {
|
||||||
id := idGen.genID()
|
id := idGen.genID()
|
||||||
|
if !IsOn() {
|
||||||
|
return newIdentifer(RefServer, id, nil)
|
||||||
|
}
|
||||||
|
|
||||||
svr := &server{
|
svr := &server{
|
||||||
refName: ref,
|
refName: ref,
|
||||||
s: s,
|
s: s,
|
||||||
@ -240,71 +264,92 @@ func RegisterServer(s Server, ref string) int64 {
|
|||||||
id: id,
|
id: id,
|
||||||
}
|
}
|
||||||
db.get().addServer(id, svr)
|
db.get().addServer(id, svr)
|
||||||
return id
|
return newIdentifer(RefServer, id, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterListenSocket registers the given listen socket s in channelz database
|
// RegisterListenSocket registers the given listen socket s in channelz database
|
||||||
// with ref as its reference name, and add it to the child list of its parent
|
// with ref as its reference name, and add it to the child list of its parent
|
||||||
// (identified by pid). It returns the unique channelz tracking id assigned to
|
// (identified by pid). It returns the unique channelz tracking id assigned to
|
||||||
// this listen socket.
|
// this listen socket.
|
||||||
func RegisterListenSocket(s Socket, pid int64, ref string) int64 {
|
//
|
||||||
if pid == 0 {
|
// If channelz is not turned ON, the channelz database is not mutated.
|
||||||
logger.Error("a ListenSocket's parent id cannot be 0")
|
func RegisterListenSocket(s Socket, pid *Identifier, ref string) (*Identifier, error) {
|
||||||
return 0
|
if pid == nil {
|
||||||
|
return nil, errors.New("a ListenSocket's parent id cannot be 0")
|
||||||
}
|
}
|
||||||
id := idGen.genID()
|
id := idGen.genID()
|
||||||
ls := &listenSocket{refName: ref, s: s, id: id, pid: pid}
|
if !IsOn() {
|
||||||
db.get().addListenSocket(id, ls, pid)
|
return newIdentifer(RefListenSocket, id, pid), nil
|
||||||
return id
|
}
|
||||||
|
|
||||||
|
ls := &listenSocket{refName: ref, s: s, id: id, pid: pid.Int()}
|
||||||
|
db.get().addListenSocket(id, ls, pid.Int())
|
||||||
|
return newIdentifer(RefListenSocket, id, pid), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterNormalSocket registers the given normal socket s in channelz database
|
// RegisterNormalSocket registers the given normal socket s in channelz database
|
||||||
// with ref as its reference name, and add it to the child list of its parent
|
// with ref as its reference name, and adds it to the child list of its parent
|
||||||
// (identified by pid). It returns the unique channelz tracking id assigned to
|
// (identified by pid). It returns the unique channelz tracking id assigned to
|
||||||
// this normal socket.
|
// this normal socket.
|
||||||
func RegisterNormalSocket(s Socket, pid int64, ref string) int64 {
|
//
|
||||||
if pid == 0 {
|
// If channelz is not turned ON, the channelz database is not mutated.
|
||||||
logger.Error("a NormalSocket's parent id cannot be 0")
|
func RegisterNormalSocket(s Socket, pid *Identifier, ref string) (*Identifier, error) {
|
||||||
return 0
|
if pid == nil {
|
||||||
|
return nil, errors.New("a NormalSocket's parent id cannot be 0")
|
||||||
}
|
}
|
||||||
id := idGen.genID()
|
id := idGen.genID()
|
||||||
ns := &normalSocket{refName: ref, s: s, id: id, pid: pid}
|
if !IsOn() {
|
||||||
db.get().addNormalSocket(id, ns, pid)
|
return newIdentifer(RefNormalSocket, id, pid), nil
|
||||||
return id
|
}
|
||||||
|
|
||||||
|
ns := &normalSocket{refName: ref, s: s, id: id, pid: pid.Int()}
|
||||||
|
db.get().addNormalSocket(id, ns, pid.Int())
|
||||||
|
return newIdentifer(RefNormalSocket, id, pid), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveEntry removes an entry with unique channelz tracking id to be id from
|
// RemoveEntry removes an entry with unique channelz tracking id to be id from
|
||||||
// channelz database.
|
// channelz database.
|
||||||
func RemoveEntry(id int64) {
|
//
|
||||||
db.get().removeEntry(id)
|
// If channelz is not turned ON, this function is a no-op.
|
||||||
|
func RemoveEntry(id *Identifier) {
|
||||||
|
if !IsOn() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
db.get().removeEntry(id.Int())
|
||||||
}
|
}
|
||||||
|
|
||||||
// TraceEventDesc is what the caller of AddTraceEvent should provide to describe the event to be added
|
// TraceEventDesc is what the caller of AddTraceEvent should provide to describe
|
||||||
// to the channel trace.
|
// the event to be added to the channel trace.
|
||||||
// The Parent field is optional. It is used for event that will be recorded in the entity's parent
|
//
|
||||||
// trace also.
|
// The Parent field is optional. It is used for an event that will be recorded
|
||||||
|
// in the entity's parent trace.
|
||||||
type TraceEventDesc struct {
|
type TraceEventDesc struct {
|
||||||
Desc string
|
Desc string
|
||||||
Severity Severity
|
Severity Severity
|
||||||
Parent *TraceEventDesc
|
Parent *TraceEventDesc
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddTraceEvent adds trace related to the entity with specified id, using the provided TraceEventDesc.
|
// AddTraceEvent adds trace related to the entity with specified id, using the
|
||||||
func AddTraceEvent(l grpclog.DepthLoggerV2, id int64, depth int, desc *TraceEventDesc) {
|
// provided TraceEventDesc.
|
||||||
for d := desc; d != nil; d = d.Parent {
|
//
|
||||||
switch d.Severity {
|
// If channelz is not turned ON, this will simply log the event descriptions.
|
||||||
case CtUnknown, CtInfo:
|
func AddTraceEvent(l grpclog.DepthLoggerV2, id *Identifier, depth int, desc *TraceEventDesc) {
|
||||||
l.InfoDepth(depth+1, d.Desc)
|
// Log only the trace description associated with the bottom most entity.
|
||||||
case CtWarning:
|
switch desc.Severity {
|
||||||
l.WarningDepth(depth+1, d.Desc)
|
case CtUnknown, CtInfo:
|
||||||
case CtError:
|
l.InfoDepth(depth+1, withParens(id)+desc.Desc)
|
||||||
l.ErrorDepth(depth+1, d.Desc)
|
case CtWarning:
|
||||||
}
|
l.WarningDepth(depth+1, withParens(id)+desc.Desc)
|
||||||
|
case CtError:
|
||||||
|
l.ErrorDepth(depth+1, withParens(id)+desc.Desc)
|
||||||
}
|
}
|
||||||
|
|
||||||
if getMaxTraceEntry() == 0 {
|
if getMaxTraceEntry() == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
db.get().traceEvent(id, desc)
|
if IsOn() {
|
||||||
|
db.get().traceEvent(id.Int(), desc)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// channelMap is the storage data structure for channelz.
|
// channelMap is the storage data structure for channelz.
|
||||||
|
75
vendor/google.golang.org/grpc/internal/channelz/id.go
generated
vendored
Normal file
75
vendor/google.golang.org/grpc/internal/channelz/id.go
generated
vendored
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2022 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 channelz
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// Identifier is an opaque identifier which uniquely identifies an entity in the
|
||||||
|
// channelz database.
|
||||||
|
type Identifier struct {
|
||||||
|
typ RefChannelType
|
||||||
|
id int64
|
||||||
|
str string
|
||||||
|
pid *Identifier
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type returns the entity type corresponding to id.
|
||||||
|
func (id *Identifier) Type() RefChannelType {
|
||||||
|
return id.typ
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int returns the integer identifier corresponding to id.
|
||||||
|
func (id *Identifier) Int() int64 {
|
||||||
|
return id.id
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns a string representation of the entity corresponding to id.
|
||||||
|
//
|
||||||
|
// This includes some information about the parent as well. Examples:
|
||||||
|
// Top-level channel: [Channel #channel-number]
|
||||||
|
// Nested channel: [Channel #parent-channel-number Channel #channel-number]
|
||||||
|
// Sub channel: [Channel #parent-channel SubChannel #subchannel-number]
|
||||||
|
func (id *Identifier) String() string {
|
||||||
|
return id.str
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equal returns true if other is the same as id.
|
||||||
|
func (id *Identifier) Equal(other *Identifier) bool {
|
||||||
|
if (id != nil) != (other != nil) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if id == nil && other == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return id.typ == other.typ && id.id == other.id && id.pid == other.pid
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewIdentifierForTesting returns a new opaque identifier to be used only for
|
||||||
|
// testing purposes.
|
||||||
|
func NewIdentifierForTesting(typ RefChannelType, id int64, pid *Identifier) *Identifier {
|
||||||
|
return newIdentifer(typ, id, pid)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newIdentifer(typ RefChannelType, id int64, pid *Identifier) *Identifier {
|
||||||
|
str := fmt.Sprintf("%s #%d", typ, id)
|
||||||
|
if pid != nil {
|
||||||
|
str = fmt.Sprintf("%s %s", pid, str)
|
||||||
|
}
|
||||||
|
return &Identifier{typ: typ, id: id, str: str, pid: pid}
|
||||||
|
}
|
91
vendor/google.golang.org/grpc/internal/channelz/logging.go
generated
vendored
91
vendor/google.golang.org/grpc/internal/channelz/logging.go
generated
vendored
@ -26,77 +26,54 @@ import (
|
|||||||
|
|
||||||
var logger = grpclog.Component("channelz")
|
var logger = grpclog.Component("channelz")
|
||||||
|
|
||||||
|
func withParens(id *Identifier) string {
|
||||||
|
return "[" + id.String() + "] "
|
||||||
|
}
|
||||||
|
|
||||||
// Info logs and adds a trace event if channelz is on.
|
// Info logs and adds a trace event if channelz is on.
|
||||||
func Info(l grpclog.DepthLoggerV2, id int64, args ...interface{}) {
|
func Info(l grpclog.DepthLoggerV2, id *Identifier, args ...interface{}) {
|
||||||
if IsOn() {
|
AddTraceEvent(l, id, 1, &TraceEventDesc{
|
||||||
AddTraceEvent(l, id, 1, &TraceEventDesc{
|
Desc: fmt.Sprint(args...),
|
||||||
Desc: fmt.Sprint(args...),
|
Severity: CtInfo,
|
||||||
Severity: CtInfo,
|
})
|
||||||
})
|
|
||||||
} else {
|
|
||||||
l.InfoDepth(1, args...)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Infof logs and adds a trace event if channelz is on.
|
// Infof logs and adds a trace event if channelz is on.
|
||||||
func Infof(l grpclog.DepthLoggerV2, id int64, format string, args ...interface{}) {
|
func Infof(l grpclog.DepthLoggerV2, id *Identifier, format string, args ...interface{}) {
|
||||||
msg := fmt.Sprintf(format, args...)
|
AddTraceEvent(l, id, 1, &TraceEventDesc{
|
||||||
if IsOn() {
|
Desc: fmt.Sprintf(format, args...),
|
||||||
AddTraceEvent(l, id, 1, &TraceEventDesc{
|
Severity: CtInfo,
|
||||||
Desc: msg,
|
})
|
||||||
Severity: CtInfo,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
l.InfoDepth(1, msg)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warning logs and adds a trace event if channelz is on.
|
// Warning logs and adds a trace event if channelz is on.
|
||||||
func Warning(l grpclog.DepthLoggerV2, id int64, args ...interface{}) {
|
func Warning(l grpclog.DepthLoggerV2, id *Identifier, args ...interface{}) {
|
||||||
if IsOn() {
|
AddTraceEvent(l, id, 1, &TraceEventDesc{
|
||||||
AddTraceEvent(l, id, 1, &TraceEventDesc{
|
Desc: fmt.Sprint(args...),
|
||||||
Desc: fmt.Sprint(args...),
|
Severity: CtWarning,
|
||||||
Severity: CtWarning,
|
})
|
||||||
})
|
|
||||||
} else {
|
|
||||||
l.WarningDepth(1, args...)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warningf logs and adds a trace event if channelz is on.
|
// Warningf logs and adds a trace event if channelz is on.
|
||||||
func Warningf(l grpclog.DepthLoggerV2, id int64, format string, args ...interface{}) {
|
func Warningf(l grpclog.DepthLoggerV2, id *Identifier, format string, args ...interface{}) {
|
||||||
msg := fmt.Sprintf(format, args...)
|
AddTraceEvent(l, id, 1, &TraceEventDesc{
|
||||||
if IsOn() {
|
Desc: fmt.Sprintf(format, args...),
|
||||||
AddTraceEvent(l, id, 1, &TraceEventDesc{
|
Severity: CtWarning,
|
||||||
Desc: msg,
|
})
|
||||||
Severity: CtWarning,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
l.WarningDepth(1, msg)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error logs and adds a trace event if channelz is on.
|
// Error logs and adds a trace event if channelz is on.
|
||||||
func Error(l grpclog.DepthLoggerV2, id int64, args ...interface{}) {
|
func Error(l grpclog.DepthLoggerV2, id *Identifier, args ...interface{}) {
|
||||||
if IsOn() {
|
AddTraceEvent(l, id, 1, &TraceEventDesc{
|
||||||
AddTraceEvent(l, id, 1, &TraceEventDesc{
|
Desc: fmt.Sprint(args...),
|
||||||
Desc: fmt.Sprint(args...),
|
Severity: CtError,
|
||||||
Severity: CtError,
|
})
|
||||||
})
|
|
||||||
} else {
|
|
||||||
l.ErrorDepth(1, args...)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Errorf logs and adds a trace event if channelz is on.
|
// Errorf logs and adds a trace event if channelz is on.
|
||||||
func Errorf(l grpclog.DepthLoggerV2, id int64, format string, args ...interface{}) {
|
func Errorf(l grpclog.DepthLoggerV2, id *Identifier, format string, args ...interface{}) {
|
||||||
msg := fmt.Sprintf(format, args...)
|
AddTraceEvent(l, id, 1, &TraceEventDesc{
|
||||||
if IsOn() {
|
Desc: fmt.Sprintf(format, args...),
|
||||||
AddTraceEvent(l, id, 1, &TraceEventDesc{
|
Severity: CtError,
|
||||||
Desc: msg,
|
})
|
||||||
Severity: CtError,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
l.ErrorDepth(1, msg)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
23
vendor/google.golang.org/grpc/internal/channelz/types.go
generated
vendored
23
vendor/google.golang.org/grpc/internal/channelz/types.go
generated
vendored
@ -686,12 +686,33 @@ const (
|
|||||||
type RefChannelType int
|
type RefChannelType int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// RefUnknown indicates an unknown entity type, the zero value for this type.
|
||||||
|
RefUnknown RefChannelType = iota
|
||||||
// RefChannel indicates the referenced entity is a Channel.
|
// RefChannel indicates the referenced entity is a Channel.
|
||||||
RefChannel RefChannelType = iota
|
RefChannel
|
||||||
// RefSubChannel indicates the referenced entity is a SubChannel.
|
// RefSubChannel indicates the referenced entity is a SubChannel.
|
||||||
RefSubChannel
|
RefSubChannel
|
||||||
|
// RefServer indicates the referenced entity is a Server.
|
||||||
|
RefServer
|
||||||
|
// RefListenSocket indicates the referenced entity is a ListenSocket.
|
||||||
|
RefListenSocket
|
||||||
|
// RefNormalSocket indicates the referenced entity is a NormalSocket.
|
||||||
|
RefNormalSocket
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var refChannelTypeToString = map[RefChannelType]string{
|
||||||
|
RefUnknown: "Unknown",
|
||||||
|
RefChannel: "Channel",
|
||||||
|
RefSubChannel: "SubChannel",
|
||||||
|
RefServer: "Server",
|
||||||
|
RefListenSocket: "ListenSocket",
|
||||||
|
RefNormalSocket: "NormalSocket",
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r RefChannelType) String() string {
|
||||||
|
return refChannelTypeToString[r]
|
||||||
|
}
|
||||||
|
|
||||||
func (c *channelTrace) dumpData() *ChannelTrace {
|
func (c *channelTrace) dumpData() *ChannelTrace {
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
ct := &ChannelTrace{EventNum: c.eventCount, CreationTime: c.createdTime}
|
ct := &ChannelTrace{EventNum: c.eventCount, CreationTime: c.createdTime}
|
||||||
|
6
vendor/google.golang.org/grpc/internal/internal.go
generated
vendored
6
vendor/google.golang.org/grpc/internal/internal.go
generated
vendored
@ -85,3 +85,9 @@ const (
|
|||||||
// that supports backend returned by grpclb balancer.
|
// that supports backend returned by grpclb balancer.
|
||||||
CredsBundleModeBackendFromBalancer = "backend-from-balancer"
|
CredsBundleModeBackendFromBalancer = "backend-from-balancer"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// RLSLoadBalancingPolicyName is the name of the RLS LB policy.
|
||||||
|
//
|
||||||
|
// It currently has an experimental suffix which would be removed once
|
||||||
|
// end-to-end testing of the policy is completed.
|
||||||
|
const RLSLoadBalancingPolicyName = "rls_experimental"
|
||||||
|
46
vendor/google.golang.org/grpc/internal/metadata/metadata.go
generated
vendored
46
vendor/google.golang.org/grpc/internal/metadata/metadata.go
generated
vendored
@ -22,6 +22,9 @@
|
|||||||
package metadata
|
package metadata
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"google.golang.org/grpc/metadata"
|
"google.golang.org/grpc/metadata"
|
||||||
"google.golang.org/grpc/resolver"
|
"google.golang.org/grpc/resolver"
|
||||||
)
|
)
|
||||||
@ -72,3 +75,46 @@ func Set(addr resolver.Address, md metadata.MD) resolver.Address {
|
|||||||
addr.Attributes = addr.Attributes.WithValue(mdKey, mdValue(md))
|
addr.Attributes = addr.Attributes.WithValue(mdKey, mdValue(md))
|
||||||
return addr
|
return addr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate returns an error if the input md contains invalid keys or values.
|
||||||
|
//
|
||||||
|
// If the header is not a pseudo-header, the following items are checked:
|
||||||
|
// - header names must contain one or more characters from this set [0-9 a-z _ - .].
|
||||||
|
// - if the header-name ends with a "-bin" suffix, no validation of the header value is performed.
|
||||||
|
// - otherwise, the header value must contain one or more characters from the set [%x20-%x7E].
|
||||||
|
func Validate(md metadata.MD) error {
|
||||||
|
for k, vals := range md {
|
||||||
|
// pseudo-header will be ignored
|
||||||
|
if k[0] == ':' {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// check key, for i that saving a conversion if not using for range
|
||||||
|
for i := 0; i < len(k); i++ {
|
||||||
|
r := k[i]
|
||||||
|
if !(r >= 'a' && r <= 'z') && !(r >= '0' && r <= '9') && r != '.' && r != '-' && r != '_' {
|
||||||
|
return fmt.Errorf("header key %q contains illegal characters not in [0-9a-z-_.]", k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if strings.HasSuffix(k, "-bin") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// check value
|
||||||
|
for _, val := range vals {
|
||||||
|
if hasNotPrintable(val) {
|
||||||
|
return fmt.Errorf("header key %q contains value with non-printable ASCII characters", k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// hasNotPrintable return true if msg contains any characters which are not in %x20-%x7E
|
||||||
|
func hasNotPrintable(msg string) bool {
|
||||||
|
// for i that saving a conversion if not using for range
|
||||||
|
for i := 0; i < len(msg); i++ {
|
||||||
|
if msg[i] < 0x20 || msg[i] > 0x7E {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
82
vendor/google.golang.org/grpc/internal/pretty/pretty.go
generated
vendored
Normal file
82
vendor/google.golang.org/grpc/internal/pretty/pretty.go
generated
vendored
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2021 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 pretty defines helper functions to pretty-print structs for logging.
|
||||||
|
package pretty
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/golang/protobuf/jsonpb"
|
||||||
|
protov1 "github.com/golang/protobuf/proto"
|
||||||
|
"google.golang.org/protobuf/encoding/protojson"
|
||||||
|
protov2 "google.golang.org/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
const jsonIndent = " "
|
||||||
|
|
||||||
|
// ToJSON marshals the input into a json string.
|
||||||
|
//
|
||||||
|
// If marshal fails, it falls back to fmt.Sprintf("%+v").
|
||||||
|
func ToJSON(e interface{}) string {
|
||||||
|
switch ee := e.(type) {
|
||||||
|
case protov1.Message:
|
||||||
|
mm := jsonpb.Marshaler{Indent: jsonIndent}
|
||||||
|
ret, err := mm.MarshalToString(ee)
|
||||||
|
if err != nil {
|
||||||
|
// This may fail for proto.Anys, e.g. for xDS v2, LDS, the v2
|
||||||
|
// messages are not imported, and this will fail because the message
|
||||||
|
// is not found.
|
||||||
|
return fmt.Sprintf("%+v", ee)
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
case protov2.Message:
|
||||||
|
mm := protojson.MarshalOptions{
|
||||||
|
Multiline: true,
|
||||||
|
Indent: jsonIndent,
|
||||||
|
}
|
||||||
|
ret, err := mm.Marshal(ee)
|
||||||
|
if err != nil {
|
||||||
|
// This may fail for proto.Anys, e.g. for xDS v2, LDS, the v2
|
||||||
|
// messages are not imported, and this will fail because the message
|
||||||
|
// is not found.
|
||||||
|
return fmt.Sprintf("%+v", ee)
|
||||||
|
}
|
||||||
|
return string(ret)
|
||||||
|
default:
|
||||||
|
ret, err := json.MarshalIndent(ee, "", jsonIndent)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Sprintf("%+v", ee)
|
||||||
|
}
|
||||||
|
return string(ret)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FormatJSON formats the input json bytes with indentation.
|
||||||
|
//
|
||||||
|
// If Indent fails, it returns the unchanged input as string.
|
||||||
|
func FormatJSON(b []byte) string {
|
||||||
|
var out bytes.Buffer
|
||||||
|
err := json.Indent(&out, b, "", jsonIndent)
|
||||||
|
if err != nil {
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
return out.String()
|
||||||
|
}
|
11
vendor/google.golang.org/grpc/internal/transport/http2_client.go
generated
vendored
11
vendor/google.golang.org/grpc/internal/transport/http2_client.go
generated
vendored
@ -132,7 +132,7 @@ type http2Client struct {
|
|||||||
kpDormant bool
|
kpDormant bool
|
||||||
|
|
||||||
// Fields below are for channelz metric collection.
|
// Fields below are for channelz metric collection.
|
||||||
channelzID int64 // channelz unique identification number
|
channelzID *channelz.Identifier
|
||||||
czData *channelzData
|
czData *channelzData
|
||||||
|
|
||||||
onGoAway func(GoAwayReason)
|
onGoAway func(GoAwayReason)
|
||||||
@ -351,8 +351,9 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts
|
|||||||
}
|
}
|
||||||
t.statsHandler.HandleConn(t.ctx, connBegin)
|
t.statsHandler.HandleConn(t.ctx, connBegin)
|
||||||
}
|
}
|
||||||
if channelz.IsOn() {
|
t.channelzID, err = channelz.RegisterNormalSocket(t, opts.ChannelzParentID, fmt.Sprintf("%s -> %s", t.localAddr, t.remoteAddr))
|
||||||
t.channelzID = channelz.RegisterNormalSocket(t, opts.ChannelzParentID, fmt.Sprintf("%s -> %s", t.localAddr, t.remoteAddr))
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
if t.keepaliveEnabled {
|
if t.keepaliveEnabled {
|
||||||
t.kpDormancyCond = sync.NewCond(&t.mu)
|
t.kpDormancyCond = sync.NewCond(&t.mu)
|
||||||
@ -898,9 +899,7 @@ func (t *http2Client) Close(err error) {
|
|||||||
t.controlBuf.finish()
|
t.controlBuf.finish()
|
||||||
t.cancel()
|
t.cancel()
|
||||||
t.conn.Close()
|
t.conn.Close()
|
||||||
if channelz.IsOn() {
|
channelz.RemoveEntry(t.channelzID)
|
||||||
channelz.RemoveEntry(t.channelzID)
|
|
||||||
}
|
|
||||||
// Append info about previous goaways if there were any, since this may be important
|
// Append info about previous goaways if there were any, since this may be important
|
||||||
// for understanding the root cause for this connection to be closed.
|
// for understanding the root cause for this connection to be closed.
|
||||||
_, goAwayDebugMessage := t.GetGoAwayReason()
|
_, goAwayDebugMessage := t.GetGoAwayReason()
|
||||||
|
18
vendor/google.golang.org/grpc/internal/transport/http2_server.go
generated
vendored
18
vendor/google.golang.org/grpc/internal/transport/http2_server.go
generated
vendored
@ -36,6 +36,7 @@ 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/internal/grpcutil"
|
"google.golang.org/grpc/internal/grpcutil"
|
||||||
|
"google.golang.org/grpc/internal/syscall"
|
||||||
|
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
@ -117,7 +118,7 @@ type http2Server struct {
|
|||||||
idle time.Time
|
idle time.Time
|
||||||
|
|
||||||
// Fields below are for channelz metric collection.
|
// Fields below are for channelz metric collection.
|
||||||
channelzID int64 // channelz unique identification number
|
channelzID *channelz.Identifier
|
||||||
czData *channelzData
|
czData *channelzData
|
||||||
bufferPool *bufferPool
|
bufferPool *bufferPool
|
||||||
|
|
||||||
@ -231,6 +232,11 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport,
|
|||||||
if kp.Timeout == 0 {
|
if kp.Timeout == 0 {
|
||||||
kp.Timeout = defaultServerKeepaliveTimeout
|
kp.Timeout = defaultServerKeepaliveTimeout
|
||||||
}
|
}
|
||||||
|
if kp.Time != infinity {
|
||||||
|
if err = syscall.SetTCPUserTimeout(conn, kp.Timeout); err != nil {
|
||||||
|
return nil, connectionErrorf(false, err, "transport: failed to set TCP_USER_TIMEOUT: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
kep := config.KeepalivePolicy
|
kep := config.KeepalivePolicy
|
||||||
if kep.MinTime == 0 {
|
if kep.MinTime == 0 {
|
||||||
kep.MinTime = defaultKeepalivePolicyMinTime
|
kep.MinTime = defaultKeepalivePolicyMinTime
|
||||||
@ -275,12 +281,12 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport,
|
|||||||
connBegin := &stats.ConnBegin{}
|
connBegin := &stats.ConnBegin{}
|
||||||
t.stats.HandleConn(t.ctx, connBegin)
|
t.stats.HandleConn(t.ctx, connBegin)
|
||||||
}
|
}
|
||||||
if channelz.IsOn() {
|
t.channelzID, err = channelz.RegisterNormalSocket(t, config.ChannelzParentID, fmt.Sprintf("%s -> %s", t.remoteAddr, t.localAddr))
|
||||||
t.channelzID = channelz.RegisterNormalSocket(t, config.ChannelzParentID, fmt.Sprintf("%s -> %s", t.remoteAddr, t.localAddr))
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
t.connectionID = atomic.AddUint64(&serverConnectionCounter, 1)
|
t.connectionID = atomic.AddUint64(&serverConnectionCounter, 1)
|
||||||
|
|
||||||
t.framer.writer.Flush()
|
t.framer.writer.Flush()
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -1210,9 +1216,7 @@ func (t *http2Server) Close() {
|
|||||||
if err := t.conn.Close(); err != nil && logger.V(logLevel) {
|
if err := t.conn.Close(); err != nil && logger.V(logLevel) {
|
||||||
logger.Infof("transport: error closing conn during Close: %v", err)
|
logger.Infof("transport: error closing conn during Close: %v", err)
|
||||||
}
|
}
|
||||||
if channelz.IsOn() {
|
channelz.RemoveEntry(t.channelzID)
|
||||||
channelz.RemoveEntry(t.channelzID)
|
|
||||||
}
|
|
||||||
// Cancel all active streams.
|
// Cancel all active streams.
|
||||||
for _, s := range streams {
|
for _, s := range streams {
|
||||||
s.cancel()
|
s.cancel()
|
||||||
|
5
vendor/google.golang.org/grpc/internal/transport/transport.go
generated
vendored
5
vendor/google.golang.org/grpc/internal/transport/transport.go
generated
vendored
@ -34,6 +34,7 @@ import (
|
|||||||
|
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
|
"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/resolver"
|
"google.golang.org/grpc/resolver"
|
||||||
@ -529,7 +530,7 @@ type ServerConfig struct {
|
|||||||
InitialConnWindowSize int32
|
InitialConnWindowSize int32
|
||||||
WriteBufferSize int
|
WriteBufferSize int
|
||||||
ReadBufferSize int
|
ReadBufferSize int
|
||||||
ChannelzParentID int64
|
ChannelzParentID *channelz.Identifier
|
||||||
MaxHeaderListSize *uint32
|
MaxHeaderListSize *uint32
|
||||||
HeaderTableSize *uint32
|
HeaderTableSize *uint32
|
||||||
}
|
}
|
||||||
@ -563,7 +564,7 @@ type ConnectOptions struct {
|
|||||||
// ReadBufferSize sets the size of read buffer, which in turn determines how much data can be read at most for one read syscall.
|
// ReadBufferSize sets the size of read buffer, which in turn determines how much data can be read at most for one read syscall.
|
||||||
ReadBufferSize int
|
ReadBufferSize int
|
||||||
// ChannelzParentID sets the addrConn id which initiate the creation of this client transport.
|
// ChannelzParentID sets the addrConn id which initiate the creation of this client transport.
|
||||||
ChannelzParentID int64
|
ChannelzParentID *channelz.Identifier
|
||||||
// MaxHeaderListSize sets the max (uncompressed) size of header list that is prepared to be received.
|
// MaxHeaderListSize sets the max (uncompressed) size of header list that is prepared to be received.
|
||||||
MaxHeaderListSize *uint32
|
MaxHeaderListSize *uint32
|
||||||
// UseProxy specifies if a proxy should be used.
|
// UseProxy specifies if a proxy should be used.
|
||||||
|
8
vendor/google.golang.org/grpc/metadata/metadata.go
generated
vendored
8
vendor/google.golang.org/grpc/metadata/metadata.go
generated
vendored
@ -188,7 +188,9 @@ func FromIncomingContext(ctx context.Context) (MD, bool) {
|
|||||||
// map, and there's no guarantee that the MD attached to the context is
|
// map, and there's no guarantee that the MD attached to the context is
|
||||||
// created using our helper functions.
|
// created using our helper functions.
|
||||||
key := strings.ToLower(k)
|
key := strings.ToLower(k)
|
||||||
out[key] = v
|
s := make([]string, len(v))
|
||||||
|
copy(s, v)
|
||||||
|
out[key] = s
|
||||||
}
|
}
|
||||||
return out, true
|
return out, true
|
||||||
}
|
}
|
||||||
@ -226,7 +228,9 @@ func FromOutgoingContext(ctx context.Context) (MD, bool) {
|
|||||||
// map, and there's no guarantee that the MD attached to the context is
|
// map, and there's no guarantee that the MD attached to the context is
|
||||||
// created using our helper functions.
|
// created using our helper functions.
|
||||||
key := strings.ToLower(k)
|
key := strings.ToLower(k)
|
||||||
out[key] = v
|
s := make([]string, len(v))
|
||||||
|
copy(s, v)
|
||||||
|
out[key] = s
|
||||||
}
|
}
|
||||||
for _, added := range raw.added {
|
for _, added := range raw.added {
|
||||||
if len(added)%2 == 1 {
|
if len(added)%2 == 1 {
|
||||||
|
128
vendor/google.golang.org/grpc/pickfirst.go
generated
vendored
128
vendor/google.golang.org/grpc/pickfirst.go
generated
vendored
@ -44,79 +44,107 @@ func (*pickfirstBuilder) Name() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type pickfirstBalancer struct {
|
type pickfirstBalancer struct {
|
||||||
state connectivity.State
|
state connectivity.State
|
||||||
cc balancer.ClientConn
|
cc balancer.ClientConn
|
||||||
sc balancer.SubConn
|
subConn balancer.SubConn
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *pickfirstBalancer) ResolverError(err error) {
|
func (b *pickfirstBalancer) ResolverError(err error) {
|
||||||
switch b.state {
|
|
||||||
case connectivity.TransientFailure, connectivity.Idle, connectivity.Connecting:
|
|
||||||
// Set a failing picker if we don't have a good picker.
|
|
||||||
b.cc.UpdateState(balancer.State{ConnectivityState: connectivity.TransientFailure,
|
|
||||||
Picker: &picker{err: fmt.Errorf("name resolver error: %v", err)},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if logger.V(2) {
|
if logger.V(2) {
|
||||||
logger.Infof("pickfirstBalancer: ResolverError called with error %v", err)
|
logger.Infof("pickfirstBalancer: ResolverError called with error %v", err)
|
||||||
}
|
}
|
||||||
|
if b.subConn == nil {
|
||||||
|
b.state = connectivity.TransientFailure
|
||||||
|
}
|
||||||
|
|
||||||
|
if b.state != connectivity.TransientFailure {
|
||||||
|
// The picker will not change since the balancer does not currently
|
||||||
|
// report an error.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
b.cc.UpdateState(balancer.State{
|
||||||
|
ConnectivityState: connectivity.TransientFailure,
|
||||||
|
Picker: &picker{err: fmt.Errorf("name resolver error: %v", err)},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *pickfirstBalancer) UpdateClientConnState(cs balancer.ClientConnState) error {
|
func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState) error {
|
||||||
if len(cs.ResolverState.Addresses) == 0 {
|
if len(state.ResolverState.Addresses) == 0 {
|
||||||
|
// The resolver reported an empty address list. Treat it like an error by
|
||||||
|
// calling b.ResolverError.
|
||||||
|
if b.subConn != nil {
|
||||||
|
// Remove the old subConn. All addresses were removed, so it is no longer
|
||||||
|
// valid.
|
||||||
|
b.cc.RemoveSubConn(b.subConn)
|
||||||
|
b.subConn = nil
|
||||||
|
}
|
||||||
b.ResolverError(errors.New("produced zero addresses"))
|
b.ResolverError(errors.New("produced zero addresses"))
|
||||||
return balancer.ErrBadResolverState
|
return balancer.ErrBadResolverState
|
||||||
}
|
}
|
||||||
if b.sc == nil {
|
|
||||||
var err error
|
if b.subConn != nil {
|
||||||
b.sc, err = b.cc.NewSubConn(cs.ResolverState.Addresses, balancer.NewSubConnOptions{})
|
b.cc.UpdateAddresses(b.subConn, state.ResolverState.Addresses)
|
||||||
if err != nil {
|
return nil
|
||||||
if logger.V(2) {
|
|
||||||
logger.Errorf("pickfirstBalancer: failed to NewSubConn: %v", err)
|
|
||||||
}
|
|
||||||
b.state = connectivity.TransientFailure
|
|
||||||
b.cc.UpdateState(balancer.State{ConnectivityState: connectivity.TransientFailure,
|
|
||||||
Picker: &picker{err: fmt.Errorf("error creating connection: %v", err)},
|
|
||||||
})
|
|
||||||
return balancer.ErrBadResolverState
|
|
||||||
}
|
|
||||||
b.state = connectivity.Idle
|
|
||||||
b.cc.UpdateState(balancer.State{ConnectivityState: connectivity.Idle, Picker: &picker{result: balancer.PickResult{SubConn: b.sc}}})
|
|
||||||
b.sc.Connect()
|
|
||||||
} else {
|
|
||||||
b.cc.UpdateAddresses(b.sc, cs.ResolverState.Addresses)
|
|
||||||
b.sc.Connect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
subConn, err := b.cc.NewSubConn(state.ResolverState.Addresses, balancer.NewSubConnOptions{})
|
||||||
|
if err != nil {
|
||||||
|
if logger.V(2) {
|
||||||
|
logger.Errorf("pickfirstBalancer: failed to NewSubConn: %v", err)
|
||||||
|
}
|
||||||
|
b.state = connectivity.TransientFailure
|
||||||
|
b.cc.UpdateState(balancer.State{
|
||||||
|
ConnectivityState: connectivity.TransientFailure,
|
||||||
|
Picker: &picker{err: fmt.Errorf("error creating connection: %v", err)},
|
||||||
|
})
|
||||||
|
return balancer.ErrBadResolverState
|
||||||
|
}
|
||||||
|
b.subConn = subConn
|
||||||
|
b.state = connectivity.Idle
|
||||||
|
b.cc.UpdateState(balancer.State{
|
||||||
|
ConnectivityState: connectivity.Idle,
|
||||||
|
Picker: &picker{result: balancer.PickResult{SubConn: b.subConn}},
|
||||||
|
})
|
||||||
|
b.subConn.Connect()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *pickfirstBalancer) UpdateSubConnState(sc balancer.SubConn, s balancer.SubConnState) {
|
func (b *pickfirstBalancer) UpdateSubConnState(subConn balancer.SubConn, state balancer.SubConnState) {
|
||||||
if logger.V(2) {
|
if logger.V(2) {
|
||||||
logger.Infof("pickfirstBalancer: UpdateSubConnState: %p, %v", sc, s)
|
logger.Infof("pickfirstBalancer: UpdateSubConnState: %p, %v", subConn, state)
|
||||||
}
|
}
|
||||||
if b.sc != sc {
|
if b.subConn != subConn {
|
||||||
if logger.V(2) {
|
if logger.V(2) {
|
||||||
logger.Infof("pickfirstBalancer: ignored state change because sc is not recognized")
|
logger.Infof("pickfirstBalancer: ignored state change because subConn is not recognized")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
b.state = s.ConnectivityState
|
b.state = state.ConnectivityState
|
||||||
if s.ConnectivityState == connectivity.Shutdown {
|
if state.ConnectivityState == connectivity.Shutdown {
|
||||||
b.sc = nil
|
b.subConn = nil
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
switch s.ConnectivityState {
|
switch state.ConnectivityState {
|
||||||
case connectivity.Ready:
|
case connectivity.Ready:
|
||||||
b.cc.UpdateState(balancer.State{ConnectivityState: s.ConnectivityState, Picker: &picker{result: balancer.PickResult{SubConn: sc}}})
|
b.cc.UpdateState(balancer.State{
|
||||||
|
ConnectivityState: state.ConnectivityState,
|
||||||
|
Picker: &picker{result: balancer.PickResult{SubConn: subConn}},
|
||||||
|
})
|
||||||
case connectivity.Connecting:
|
case connectivity.Connecting:
|
||||||
b.cc.UpdateState(balancer.State{ConnectivityState: s.ConnectivityState, Picker: &picker{err: balancer.ErrNoSubConnAvailable}})
|
b.cc.UpdateState(balancer.State{
|
||||||
|
ConnectivityState: state.ConnectivityState,
|
||||||
|
Picker: &picker{err: balancer.ErrNoSubConnAvailable},
|
||||||
|
})
|
||||||
case connectivity.Idle:
|
case connectivity.Idle:
|
||||||
b.cc.UpdateState(balancer.State{ConnectivityState: s.ConnectivityState, Picker: &idlePicker{sc: sc}})
|
b.cc.UpdateState(balancer.State{
|
||||||
|
ConnectivityState: state.ConnectivityState,
|
||||||
|
Picker: &idlePicker{subConn: subConn},
|
||||||
|
})
|
||||||
case connectivity.TransientFailure:
|
case connectivity.TransientFailure:
|
||||||
b.cc.UpdateState(balancer.State{
|
b.cc.UpdateState(balancer.State{
|
||||||
ConnectivityState: s.ConnectivityState,
|
ConnectivityState: state.ConnectivityState,
|
||||||
Picker: &picker{err: s.ConnectionError},
|
Picker: &picker{err: state.ConnectionError},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,8 +153,8 @@ func (b *pickfirstBalancer) Close() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *pickfirstBalancer) ExitIdle() {
|
func (b *pickfirstBalancer) ExitIdle() {
|
||||||
if b.sc != nil && b.state == connectivity.Idle {
|
if b.subConn != nil && b.state == connectivity.Idle {
|
||||||
b.sc.Connect()
|
b.subConn.Connect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,18 +163,18 @@ type picker struct {
|
|||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *picker) Pick(info balancer.PickInfo) (balancer.PickResult, error) {
|
func (p *picker) Pick(balancer.PickInfo) (balancer.PickResult, error) {
|
||||||
return p.result, p.err
|
return p.result, p.err
|
||||||
}
|
}
|
||||||
|
|
||||||
// idlePicker is used when the SubConn is IDLE and kicks the SubConn into
|
// idlePicker is used when the SubConn is IDLE and kicks the SubConn into
|
||||||
// CONNECTING when Pick is called.
|
// CONNECTING when Pick is called.
|
||||||
type idlePicker struct {
|
type idlePicker struct {
|
||||||
sc balancer.SubConn
|
subConn balancer.SubConn
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *idlePicker) Pick(info balancer.PickInfo) (balancer.PickResult, error) {
|
func (i *idlePicker) Pick(balancer.PickInfo) (balancer.PickResult, error) {
|
||||||
i.sc.Connect()
|
i.subConn.Connect()
|
||||||
return balancer.PickResult{}, balancer.ErrNoSubConnAvailable
|
return balancer.PickResult{}, balancer.ErrNoSubConnAvailable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
8
vendor/google.golang.org/grpc/resolver/resolver.go
generated
vendored
8
vendor/google.golang.org/grpc/resolver/resolver.go
generated
vendored
@ -27,6 +27,7 @@ import (
|
|||||||
|
|
||||||
"google.golang.org/grpc/attributes"
|
"google.golang.org/grpc/attributes"
|
||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
|
"google.golang.org/grpc/internal/pretty"
|
||||||
"google.golang.org/grpc/serviceconfig"
|
"google.golang.org/grpc/serviceconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -139,13 +140,18 @@ type Address struct {
|
|||||||
|
|
||||||
// Equal returns whether a and o are identical. Metadata is compared directly,
|
// Equal returns whether a and o are identical. Metadata is compared directly,
|
||||||
// not with any recursive introspection.
|
// not with any recursive introspection.
|
||||||
func (a *Address) Equal(o Address) bool {
|
func (a Address) Equal(o Address) bool {
|
||||||
return a.Addr == o.Addr && a.ServerName == o.ServerName &&
|
return a.Addr == o.Addr && a.ServerName == o.ServerName &&
|
||||||
a.Attributes.Equal(o.Attributes) &&
|
a.Attributes.Equal(o.Attributes) &&
|
||||||
a.BalancerAttributes.Equal(o.BalancerAttributes) &&
|
a.BalancerAttributes.Equal(o.BalancerAttributes) &&
|
||||||
a.Type == o.Type && a.Metadata == o.Metadata
|
a.Type == o.Type && a.Metadata == o.Metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// String returns JSON formatted string representation of the address.
|
||||||
|
func (a Address) String() string {
|
||||||
|
return pretty.ToJSON(a)
|
||||||
|
}
|
||||||
|
|
||||||
// BuildOptions includes additional information for the builder to create
|
// BuildOptions includes additional information for the builder to create
|
||||||
// the resolver.
|
// the resolver.
|
||||||
type BuildOptions struct {
|
type BuildOptions struct {
|
||||||
|
23
vendor/google.golang.org/grpc/resolver_conn_wrapper.go
generated
vendored
23
vendor/google.golang.org/grpc/resolver_conn_wrapper.go
generated
vendored
@ -19,7 +19,6 @@
|
|||||||
package grpc
|
package grpc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
@ -27,6 +26,7 @@ import (
|
|||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
"google.golang.org/grpc/internal/channelz"
|
"google.golang.org/grpc/internal/channelz"
|
||||||
"google.golang.org/grpc/internal/grpcsync"
|
"google.golang.org/grpc/internal/grpcsync"
|
||||||
|
"google.golang.org/grpc/internal/pretty"
|
||||||
"google.golang.org/grpc/resolver"
|
"google.golang.org/grpc/resolver"
|
||||||
"google.golang.org/grpc/serviceconfig"
|
"google.golang.org/grpc/serviceconfig"
|
||||||
)
|
)
|
||||||
@ -97,10 +97,7 @@ func (ccr *ccResolverWrapper) UpdateState(s resolver.State) error {
|
|||||||
if ccr.done.HasFired() {
|
if ccr.done.HasFired() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
channelz.Infof(logger, ccr.cc.channelzID, "ccResolverWrapper: sending update to cc: %v", s)
|
ccr.addChannelzTraceEvent(s)
|
||||||
if channelz.IsOn() {
|
|
||||||
ccr.addChannelzTraceEvent(s)
|
|
||||||
}
|
|
||||||
ccr.curState = s
|
ccr.curState = s
|
||||||
if err := ccr.cc.updateResolverState(ccr.curState, nil); err == balancer.ErrBadResolverState {
|
if err := ccr.cc.updateResolverState(ccr.curState, nil); err == balancer.ErrBadResolverState {
|
||||||
return balancer.ErrBadResolverState
|
return balancer.ErrBadResolverState
|
||||||
@ -125,10 +122,7 @@ func (ccr *ccResolverWrapper) NewAddress(addrs []resolver.Address) {
|
|||||||
if ccr.done.HasFired() {
|
if ccr.done.HasFired() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
channelz.Infof(logger, ccr.cc.channelzID, "ccResolverWrapper: sending new addresses to cc: %v", addrs)
|
ccr.addChannelzTraceEvent(resolver.State{Addresses: addrs, ServiceConfig: ccr.curState.ServiceConfig})
|
||||||
if channelz.IsOn() {
|
|
||||||
ccr.addChannelzTraceEvent(resolver.State{Addresses: addrs, ServiceConfig: ccr.curState.ServiceConfig})
|
|
||||||
}
|
|
||||||
ccr.curState.Addresses = addrs
|
ccr.curState.Addresses = addrs
|
||||||
ccr.cc.updateResolverState(ccr.curState, nil)
|
ccr.cc.updateResolverState(ccr.curState, nil)
|
||||||
}
|
}
|
||||||
@ -141,7 +135,7 @@ func (ccr *ccResolverWrapper) NewServiceConfig(sc string) {
|
|||||||
if ccr.done.HasFired() {
|
if ccr.done.HasFired() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
channelz.Infof(logger, ccr.cc.channelzID, "ccResolverWrapper: got new service config: %v", sc)
|
channelz.Infof(logger, ccr.cc.channelzID, "ccResolverWrapper: got new service config: %s", sc)
|
||||||
if ccr.cc.dopts.disableServiceConfig {
|
if ccr.cc.dopts.disableServiceConfig {
|
||||||
channelz.Info(logger, ccr.cc.channelzID, "Service config lookups disabled; ignoring config")
|
channelz.Info(logger, ccr.cc.channelzID, "Service config lookups disabled; ignoring config")
|
||||||
return
|
return
|
||||||
@ -151,9 +145,7 @@ func (ccr *ccResolverWrapper) NewServiceConfig(sc string) {
|
|||||||
channelz.Warningf(logger, ccr.cc.channelzID, "ccResolverWrapper: error parsing service config: %v", scpr.Err)
|
channelz.Warningf(logger, ccr.cc.channelzID, "ccResolverWrapper: error parsing service config: %v", scpr.Err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if channelz.IsOn() {
|
ccr.addChannelzTraceEvent(resolver.State{Addresses: ccr.curState.Addresses, ServiceConfig: scpr})
|
||||||
ccr.addChannelzTraceEvent(resolver.State{Addresses: ccr.curState.Addresses, ServiceConfig: scpr})
|
|
||||||
}
|
|
||||||
ccr.curState.ServiceConfig = scpr
|
ccr.curState.ServiceConfig = scpr
|
||||||
ccr.cc.updateResolverState(ccr.curState, nil)
|
ccr.cc.updateResolverState(ccr.curState, nil)
|
||||||
}
|
}
|
||||||
@ -180,8 +172,5 @@ func (ccr *ccResolverWrapper) addChannelzTraceEvent(s resolver.State) {
|
|||||||
} else if len(ccr.curState.Addresses) == 0 && len(s.Addresses) > 0 {
|
} else if len(ccr.curState.Addresses) == 0 && len(s.Addresses) > 0 {
|
||||||
updates = append(updates, "resolver returned new addresses")
|
updates = append(updates, "resolver returned new addresses")
|
||||||
}
|
}
|
||||||
channelz.AddTraceEvent(logger, ccr.cc.channelzID, 0, &channelz.TraceEventDesc{
|
channelz.Infof(logger, ccr.cc.channelzID, "Resolver state updated: %s (%v)", pretty.ToJSON(s), strings.Join(updates, "; "))
|
||||||
Desc: fmt.Sprintf("Resolver state updated: %+v (%v)", s, strings.Join(updates, "; ")),
|
|
||||||
Severity: channelz.CtInfo,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
41
vendor/google.golang.org/grpc/server.go
generated
vendored
41
vendor/google.golang.org/grpc/server.go
generated
vendored
@ -134,7 +134,7 @@ type Server struct {
|
|||||||
channelzRemoveOnce sync.Once
|
channelzRemoveOnce sync.Once
|
||||||
serveWG sync.WaitGroup // counts active Serve goroutines for GracefulStop
|
serveWG sync.WaitGroup // counts active Serve goroutines for GracefulStop
|
||||||
|
|
||||||
channelzID int64 // channelz unique identification number
|
channelzID *channelz.Identifier
|
||||||
czData *channelzData
|
czData *channelzData
|
||||||
|
|
||||||
serverWorkerChannels []chan *serverWorkerData
|
serverWorkerChannels []chan *serverWorkerData
|
||||||
@ -584,9 +584,8 @@ func NewServer(opt ...ServerOption) *Server {
|
|||||||
s.initServerWorkers()
|
s.initServerWorkers()
|
||||||
}
|
}
|
||||||
|
|
||||||
if channelz.IsOn() {
|
s.channelzID = channelz.RegisterServer(&channelzServer{s}, "")
|
||||||
s.channelzID = channelz.RegisterServer(&channelzServer{s}, "")
|
channelz.Info(logger, s.channelzID, "Server created")
|
||||||
}
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -712,7 +711,7 @@ var ErrServerStopped = errors.New("grpc: the server has been stopped")
|
|||||||
|
|
||||||
type listenSocket struct {
|
type listenSocket struct {
|
||||||
net.Listener
|
net.Listener
|
||||||
channelzID int64
|
channelzID *channelz.Identifier
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *listenSocket) ChannelzMetric() *channelz.SocketInternalMetric {
|
func (l *listenSocket) ChannelzMetric() *channelz.SocketInternalMetric {
|
||||||
@ -724,9 +723,8 @@ func (l *listenSocket) ChannelzMetric() *channelz.SocketInternalMetric {
|
|||||||
|
|
||||||
func (l *listenSocket) Close() error {
|
func (l *listenSocket) Close() error {
|
||||||
err := l.Listener.Close()
|
err := l.Listener.Close()
|
||||||
if channelz.IsOn() {
|
channelz.RemoveEntry(l.channelzID)
|
||||||
channelz.RemoveEntry(l.channelzID)
|
channelz.Info(logger, l.channelzID, "ListenSocket deleted")
|
||||||
}
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -759,11 +757,6 @@ func (s *Server) Serve(lis net.Listener) error {
|
|||||||
ls := &listenSocket{Listener: lis}
|
ls := &listenSocket{Listener: lis}
|
||||||
s.lis[ls] = true
|
s.lis[ls] = true
|
||||||
|
|
||||||
if channelz.IsOn() {
|
|
||||||
ls.channelzID = channelz.RegisterListenSocket(ls, s.channelzID, lis.Addr().String())
|
|
||||||
}
|
|
||||||
s.mu.Unlock()
|
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
if s.lis != nil && s.lis[ls] {
|
if s.lis != nil && s.lis[ls] {
|
||||||
@ -773,8 +766,16 @@ func (s *Server) Serve(lis net.Listener) error {
|
|||||||
s.mu.Unlock()
|
s.mu.Unlock()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
var tempDelay time.Duration // how long to sleep on accept failure
|
var err error
|
||||||
|
ls.channelzID, err = channelz.RegisterListenSocket(ls, s.channelzID, lis.Addr().String())
|
||||||
|
if err != nil {
|
||||||
|
s.mu.Unlock()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
s.mu.Unlock()
|
||||||
|
channelz.Info(logger, ls.channelzID, "ListenSocket created")
|
||||||
|
|
||||||
|
var tempDelay time.Duration // how long to sleep on accept failure
|
||||||
for {
|
for {
|
||||||
rawConn, err := lis.Accept()
|
rawConn, err := lis.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1709,11 +1710,7 @@ func (s *Server) Stop() {
|
|||||||
s.done.Fire()
|
s.done.Fire()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
s.channelzRemoveOnce.Do(func() {
|
s.channelzRemoveOnce.Do(func() { channelz.RemoveEntry(s.channelzID) })
|
||||||
if channelz.IsOn() {
|
|
||||||
channelz.RemoveEntry(s.channelzID)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
listeners := s.lis
|
listeners := s.lis
|
||||||
@ -1751,11 +1748,7 @@ func (s *Server) GracefulStop() {
|
|||||||
s.quit.Fire()
|
s.quit.Fire()
|
||||||
defer s.done.Fire()
|
defer s.done.Fire()
|
||||||
|
|
||||||
s.channelzRemoveOnce.Do(func() {
|
s.channelzRemoveOnce.Do(func() { channelz.RemoveEntry(s.channelzID) })
|
||||||
if channelz.IsOn() {
|
|
||||||
channelz.RemoveEntry(s.channelzID)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
if s.conns == nil {
|
if s.conns == nil {
|
||||||
s.mu.Unlock()
|
s.mu.Unlock()
|
||||||
|
3
vendor/google.golang.org/grpc/service_config.go
generated
vendored
3
vendor/google.golang.org/grpc/service_config.go
generated
vendored
@ -381,6 +381,9 @@ func init() {
|
|||||||
//
|
//
|
||||||
// If any of them is NOT *ServiceConfig, return false.
|
// If any of them is NOT *ServiceConfig, return false.
|
||||||
func equalServiceConfig(a, b serviceconfig.Config) bool {
|
func equalServiceConfig(a, b serviceconfig.Config) bool {
|
||||||
|
if a == nil && b == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
aa, ok := a.(*ServiceConfig)
|
aa, ok := a.(*ServiceConfig)
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
|
24
vendor/google.golang.org/grpc/stream.go
generated
vendored
24
vendor/google.golang.org/grpc/stream.go
generated
vendored
@ -36,6 +36,7 @@ import (
|
|||||||
"google.golang.org/grpc/internal/channelz"
|
"google.golang.org/grpc/internal/channelz"
|
||||||
"google.golang.org/grpc/internal/grpcrand"
|
"google.golang.org/grpc/internal/grpcrand"
|
||||||
"google.golang.org/grpc/internal/grpcutil"
|
"google.golang.org/grpc/internal/grpcutil"
|
||||||
|
imetadata "google.golang.org/grpc/internal/metadata"
|
||||||
iresolver "google.golang.org/grpc/internal/resolver"
|
iresolver "google.golang.org/grpc/internal/resolver"
|
||||||
"google.golang.org/grpc/internal/serviceconfig"
|
"google.golang.org/grpc/internal/serviceconfig"
|
||||||
"google.golang.org/grpc/internal/transport"
|
"google.golang.org/grpc/internal/transport"
|
||||||
@ -166,6 +167,11 @@ func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (_ ClientStream, err error) {
|
func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (_ ClientStream, err error) {
|
||||||
|
if md, _, ok := metadata.FromOutgoingContextRaw(ctx); ok {
|
||||||
|
if err := imetadata.Validate(md); err != nil {
|
||||||
|
return nil, status.Error(codes.Internal, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
if channelz.IsOn() {
|
if channelz.IsOn() {
|
||||||
cc.incrCallsStarted()
|
cc.incrCallsStarted()
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -456,7 +462,7 @@ type clientStream struct {
|
|||||||
|
|
||||||
retryThrottler *retryThrottler // The throttler active when the RPC began.
|
retryThrottler *retryThrottler // The throttler active when the RPC began.
|
||||||
|
|
||||||
binlog *binarylog.MethodLogger // Binary logger, can be nil.
|
binlog binarylog.MethodLogger // Binary logger, can be nil.
|
||||||
// serverHeaderBinlogged is a boolean for whether server header has been
|
// serverHeaderBinlogged is a boolean for whether server header has been
|
||||||
// logged. Server header will be logged when the first time one of those
|
// logged. Server header will be logged when the first time one of those
|
||||||
// happens: stream.Header(), stream.Recv().
|
// happens: stream.Header(), stream.Recv().
|
||||||
@ -1428,7 +1434,7 @@ type serverStream struct {
|
|||||||
|
|
||||||
statsHandler stats.Handler
|
statsHandler stats.Handler
|
||||||
|
|
||||||
binlog *binarylog.MethodLogger
|
binlog binarylog.MethodLogger
|
||||||
// serverHeaderBinlogged indicates whether server header has been logged. It
|
// serverHeaderBinlogged indicates whether server header has been logged. It
|
||||||
// will happen when one of the following two happens: stream.SendHeader(),
|
// will happen when one of the following two happens: stream.SendHeader(),
|
||||||
// stream.Send().
|
// stream.Send().
|
||||||
@ -1448,11 +1454,20 @@ func (ss *serverStream) SetHeader(md metadata.MD) error {
|
|||||||
if md.Len() == 0 {
|
if md.Len() == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
err := imetadata.Validate(md)
|
||||||
|
if err != nil {
|
||||||
|
return status.Error(codes.Internal, err.Error())
|
||||||
|
}
|
||||||
return ss.s.SetHeader(md)
|
return ss.s.SetHeader(md)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *serverStream) SendHeader(md metadata.MD) error {
|
func (ss *serverStream) SendHeader(md metadata.MD) error {
|
||||||
err := ss.t.WriteHeader(ss.s, md)
|
err := imetadata.Validate(md)
|
||||||
|
if err != nil {
|
||||||
|
return status.Error(codes.Internal, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ss.t.WriteHeader(ss.s, md)
|
||||||
if ss.binlog != nil && !ss.serverHeaderBinlogged {
|
if ss.binlog != nil && !ss.serverHeaderBinlogged {
|
||||||
h, _ := ss.s.Header()
|
h, _ := ss.s.Header()
|
||||||
ss.binlog.Log(&binarylog.ServerHeader{
|
ss.binlog.Log(&binarylog.ServerHeader{
|
||||||
@ -1467,6 +1482,9 @@ func (ss *serverStream) SetTrailer(md metadata.MD) {
|
|||||||
if md.Len() == 0 {
|
if md.Len() == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if err := imetadata.Validate(md); err != nil {
|
||||||
|
logger.Errorf("stream: failed to validate md when setting trailer, err: %v", err)
|
||||||
|
}
|
||||||
ss.s.SetTrailer(md)
|
ss.s.SetTrailer(md)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
vendor/google.golang.org/grpc/version.go
generated
vendored
2
vendor/google.golang.org/grpc/version.go
generated
vendored
@ -19,4 +19,4 @@
|
|||||||
package grpc
|
package grpc
|
||||||
|
|
||||||
// Version is the current grpc version.
|
// Version is the current grpc version.
|
||||||
const Version = "1.45.0"
|
const Version = "1.46.0"
|
||||||
|
5
vendor/modules.txt
vendored
5
vendor/modules.txt
vendored
@ -639,7 +639,7 @@ google.golang.org/appengine/urlfetch
|
|||||||
google.golang.org/genproto/googleapis/api/httpbody
|
google.golang.org/genproto/googleapis/api/httpbody
|
||||||
google.golang.org/genproto/googleapis/rpc/status
|
google.golang.org/genproto/googleapis/rpc/status
|
||||||
google.golang.org/genproto/protobuf/field_mask
|
google.golang.org/genproto/protobuf/field_mask
|
||||||
# google.golang.org/grpc v1.45.0
|
# google.golang.org/grpc v1.46.0
|
||||||
## explicit; go 1.14
|
## explicit; go 1.14
|
||||||
google.golang.org/grpc
|
google.golang.org/grpc
|
||||||
google.golang.org/grpc/attributes
|
google.golang.org/grpc/attributes
|
||||||
@ -649,6 +649,7 @@ google.golang.org/grpc/balancer/base
|
|||||||
google.golang.org/grpc/balancer/grpclb/state
|
google.golang.org/grpc/balancer/grpclb/state
|
||||||
google.golang.org/grpc/balancer/roundrobin
|
google.golang.org/grpc/balancer/roundrobin
|
||||||
google.golang.org/grpc/binarylog/grpc_binarylog_v1
|
google.golang.org/grpc/binarylog/grpc_binarylog_v1
|
||||||
|
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
|
||||||
@ -661,6 +662,7 @@ google.golang.org/grpc/health
|
|||||||
google.golang.org/grpc/health/grpc_health_v1
|
google.golang.org/grpc/health/grpc_health_v1
|
||||||
google.golang.org/grpc/internal
|
google.golang.org/grpc/internal
|
||||||
google.golang.org/grpc/internal/backoff
|
google.golang.org/grpc/internal/backoff
|
||||||
|
google.golang.org/grpc/internal/balancer/gracefulswitch
|
||||||
google.golang.org/grpc/internal/balancerload
|
google.golang.org/grpc/internal/balancerload
|
||||||
google.golang.org/grpc/internal/binarylog
|
google.golang.org/grpc/internal/binarylog
|
||||||
google.golang.org/grpc/internal/buffer
|
google.golang.org/grpc/internal/buffer
|
||||||
@ -672,6 +674,7 @@ google.golang.org/grpc/internal/grpcrand
|
|||||||
google.golang.org/grpc/internal/grpcsync
|
google.golang.org/grpc/internal/grpcsync
|
||||||
google.golang.org/grpc/internal/grpcutil
|
google.golang.org/grpc/internal/grpcutil
|
||||||
google.golang.org/grpc/internal/metadata
|
google.golang.org/grpc/internal/metadata
|
||||||
|
google.golang.org/grpc/internal/pretty
|
||||||
google.golang.org/grpc/internal/resolver
|
google.golang.org/grpc/internal/resolver
|
||||||
google.golang.org/grpc/internal/resolver/dns
|
google.golang.org/grpc/internal/resolver/dns
|
||||||
google.golang.org/grpc/internal/resolver/passthrough
|
google.golang.org/grpc/internal/resolver/passthrough
|
||||||
|
Loading…
Reference in New Issue
Block a user