mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-05-18 09:17:49 +08:00
vendor: google.golang.org/grpc v1.58.3
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
7f93616ff1
commit
4932eecc3f
6
go.mod
6
go.mod
@ -43,7 +43,7 @@ require (
|
|||||||
golang.org/x/mod v0.11.0
|
golang.org/x/mod v0.11.0
|
||||||
golang.org/x/sync v0.3.0
|
golang.org/x/sync v0.3.0
|
||||||
golang.org/x/term v0.13.0
|
golang.org/x/term v0.13.0
|
||||||
google.golang.org/grpc v1.53.0
|
google.golang.org/grpc v1.58.3
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
k8s.io/api v0.26.7
|
k8s.io/api v0.26.7
|
||||||
k8s.io/apimachinery v0.26.7
|
k8s.io/apimachinery v0.26.7
|
||||||
@ -151,7 +151,9 @@ require (
|
|||||||
golang.org/x/time v0.3.0 // indirect
|
golang.org/x/time v0.3.0 // indirect
|
||||||
golang.org/x/tools v0.10.0 // indirect
|
golang.org/x/tools v0.10.0 // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect
|
google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 // indirect
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 // indirect
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect
|
||||||
google.golang.org/protobuf v1.31.0 // indirect
|
google.golang.org/protobuf v1.31.0 // indirect
|
||||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
|
20
go.sum
20
go.sum
@ -13,14 +13,14 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV
|
|||||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||||
cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys=
|
cloud.google.com/go v0.110.4 h1:1JYyxKMN9hd5dR2MYTPWkGUgcoxVVhg0LKNKEo0qvmk=
|
||||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||||
cloud.google.com/go/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg=
|
cloud.google.com/go/compute v1.21.0 h1:JNBsyXVoOoNJtTQcnEY5uYpZIbeCTYIeDe0Xh1bySMk=
|
||||||
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
||||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||||
@ -123,6 +123,7 @@ github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWH
|
|||||||
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-20211011173535-cb28da3451f1/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-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k=
|
||||||
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE=
|
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE=
|
||||||
github.com/compose-spec/compose-go v1.20.0 h1:h4ZKOst1EF/DwZp7dWkb+wbTVE4nEyT9Lc89to84Ol4=
|
github.com/compose-spec/compose-go v1.20.0 h1:h4ZKOst1EF/DwZp7dWkb+wbTVE4nEyT9Lc89to84Ol4=
|
||||||
github.com/compose-spec/compose-go v1.20.0/go.mod h1:+MdqXV4RA7wdFsahh/Kb8U0pAJqkg7mr4PM9tFKU8RM=
|
github.com/compose-spec/compose-go v1.20.0/go.mod h1:+MdqXV4RA7wdFsahh/Kb8U0pAJqkg7mr4PM9tFKU8RM=
|
||||||
@ -188,6 +189,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.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/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/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA=
|
||||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
|
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
|
||||||
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
|
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
|
||||||
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||||
@ -230,8 +232,8 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
|||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ=
|
|
||||||
github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
|
github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
|
||||||
|
github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE=
|
||||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
@ -832,8 +834,12 @@ google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6D
|
|||||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||||
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA=
|
google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 h1:Z0hjGZePRE0ZBWotvtrwxFNrNE9CUAGtplaDK5NNI/g=
|
||||||
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s=
|
google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98/go.mod h1:S7mY02OqCJTD0E1OiQy1F72PWFB4bZJ87cAtLPYgDR0=
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 h1:FmF5cCW94Ij59cfpoLiwTgodWmm60eEV0CjlsVg2fuw=
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
|
||||||
google.golang.org/grpc v1.0.5/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
google.golang.org/grpc v1.0.5/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||||
@ -851,8 +857,8 @@ google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTp
|
|||||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||||
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.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
|
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
|
||||||
google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc=
|
google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ=
|
||||||
google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw=
|
google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||||
|
202
vendor/google.golang.org/genproto/googleapis/api/LICENSE
generated
vendored
Normal file
202
vendor/google.golang.org/genproto/googleapis/api/LICENSE
generated
vendored
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
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.
|
4
vendor/google.golang.org/genproto/googleapis/api/httpbody/httpbody.pb.go
generated
vendored
4
vendor/google.golang.org/genproto/googleapis/api/httpbody/httpbody.pb.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2015 Google LLC
|
// Copyright 2023 Google LLC
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
@ -15,7 +15,7 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.26.0
|
// protoc-gen-go v1.26.0
|
||||||
// protoc v3.12.2
|
// protoc v3.21.9
|
||||||
// source: google/api/httpbody.proto
|
// source: google/api/httpbody.proto
|
||||||
|
|
||||||
package httpbody
|
package httpbody
|
||||||
|
202
vendor/google.golang.org/genproto/googleapis/rpc/LICENSE
generated
vendored
Normal file
202
vendor/google.golang.org/genproto/googleapis/rpc/LICENSE
generated
vendored
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
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.
|
25
vendor/google.golang.org/grpc/CONTRIBUTING.md
generated
vendored
25
vendor/google.golang.org/grpc/CONTRIBUTING.md
generated
vendored
@ -20,6 +20,15 @@ How to get your contributions merged smoothly and quickly.
|
|||||||
both author's & review's time is wasted. Create more PRs to address different
|
both author's & review's time is wasted. Create more PRs to address different
|
||||||
concerns and everyone will be happy.
|
concerns and everyone will be happy.
|
||||||
|
|
||||||
|
- If you are searching for features to work on, issues labeled [Status: Help
|
||||||
|
Wanted](https://github.com/grpc/grpc-go/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22Status%3A+Help+Wanted%22)
|
||||||
|
is a great place to start. These issues are well-documented and usually can be
|
||||||
|
resolved with a single pull request.
|
||||||
|
|
||||||
|
- If you are adding a new file, make sure it has the copyright message template
|
||||||
|
at the top as a comment. You can copy over the message from an existing file
|
||||||
|
and update the year.
|
||||||
|
|
||||||
- The grpc package should only depend on standard Go packages and a small number
|
- The grpc package should only depend on standard Go packages and a small number
|
||||||
of exceptions. If your contribution introduces new dependencies which are NOT
|
of exceptions. If your contribution introduces new dependencies which are NOT
|
||||||
in the [list](https://godoc.org/google.golang.org/grpc?imports), you need a
|
in the [list](https://godoc.org/google.golang.org/grpc?imports), you need a
|
||||||
@ -32,14 +41,18 @@ How to get your contributions merged smoothly and quickly.
|
|||||||
- Provide a good **PR description** as a record of **what** change is being made
|
- Provide a good **PR description** as a record of **what** change is being made
|
||||||
and **why** it was made. Link to a github issue if it exists.
|
and **why** it was made. Link to a github issue if it exists.
|
||||||
|
|
||||||
- Don't fix code style and formatting unless you are already changing that line
|
- If you want to fix formatting or style, consider whether your changes are an
|
||||||
to address an issue. PRs with irrelevant changes won't be merged. If you do
|
obvious improvement or might be considered a personal preference. If a style
|
||||||
want to fix formatting or style, do that in a separate PR.
|
change is based on preference, it likely will not be accepted. If it corrects
|
||||||
|
widely agreed-upon anti-patterns, then please do create a PR and explain the
|
||||||
|
benefits of the change.
|
||||||
|
|
||||||
- Unless your PR is trivial, you should expect there will be reviewer comments
|
- Unless your PR is trivial, you should expect there will be reviewer comments
|
||||||
that you'll need to address before merging. We expect you to be reasonably
|
that you'll need to address before merging. We'll mark it as `Status: Requires
|
||||||
responsive to those comments, otherwise the PR will be closed after 2-3 weeks
|
Reporter Clarification` if we expect you to respond to these comments in a
|
||||||
of inactivity.
|
timely manner. If the PR remains inactive for 6 days, it will be marked as
|
||||||
|
`stale` and automatically close 7 days after that if we don't hear back from
|
||||||
|
you.
|
||||||
|
|
||||||
- Maintain **clean commit history** and use **meaningful commit messages**. PRs
|
- Maintain **clean commit history** and use **meaningful commit messages**. PRs
|
||||||
with messy commit history are difficult to review and won't be merged. Use
|
with messy commit history are difficult to review and won't be merged. Use
|
||||||
|
58
vendor/google.golang.org/grpc/README.md
generated
vendored
58
vendor/google.golang.org/grpc/README.md
generated
vendored
@ -14,21 +14,14 @@ RPC framework that puts mobile and HTTP/2 first. For more information see the
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
With [Go module][] support (Go 1.11+), simply add the following import
|
Simply add the following import to your code, and then `go [build|run|test]`
|
||||||
|
will automatically fetch the necessary dependencies:
|
||||||
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "google.golang.org/grpc"
|
import "google.golang.org/grpc"
|
||||||
```
|
```
|
||||||
|
|
||||||
to your code, and then `go [build|run|test]` will automatically fetch the
|
|
||||||
necessary dependencies.
|
|
||||||
|
|
||||||
Otherwise, to install the `grpc-go` package, run the following command:
|
|
||||||
|
|
||||||
```console
|
|
||||||
$ go get -u google.golang.org/grpc
|
|
||||||
```
|
|
||||||
|
|
||||||
> **Note:** If you are trying to access `grpc-go` from **China**, see the
|
> **Note:** If you are trying to access `grpc-go` from **China**, see the
|
||||||
> [FAQ](#FAQ) below.
|
> [FAQ](#FAQ) below.
|
||||||
|
|
||||||
@ -56,15 +49,6 @@ To build Go code, there are several options:
|
|||||||
|
|
||||||
- Set up a VPN and access google.golang.org through that.
|
- Set up a VPN and access google.golang.org through that.
|
||||||
|
|
||||||
- Without Go module support: `git clone` the repo manually:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
git clone https://github.com/grpc/grpc-go.git $GOPATH/src/google.golang.org/grpc
|
|
||||||
```
|
|
||||||
|
|
||||||
You will need to do the same for all of grpc's dependencies in `golang.org`,
|
|
||||||
e.g. `golang.org/x/net`.
|
|
||||||
|
|
||||||
- With Go module support: it is possible to use the `replace` feature of `go
|
- With Go module support: it is possible to use the `replace` feature of `go
|
||||||
mod` to create aliases for golang.org packages. In your project's directory:
|
mod` to create aliases for golang.org packages. In your project's directory:
|
||||||
|
|
||||||
@ -76,33 +60,13 @@ To build Go code, there are several options:
|
|||||||
```
|
```
|
||||||
|
|
||||||
Again, this will need to be done for all transitive dependencies hosted on
|
Again, this will need to be done for all transitive dependencies hosted on
|
||||||
golang.org as well. For details, refer to [golang/go issue #28652](https://github.com/golang/go/issues/28652).
|
golang.org as well. For details, refer to [golang/go issue
|
||||||
|
#28652](https://github.com/golang/go/issues/28652).
|
||||||
|
|
||||||
### Compiling error, undefined: grpc.SupportPackageIsVersion
|
### Compiling error, undefined: grpc.SupportPackageIsVersion
|
||||||
|
|
||||||
#### If you are using Go modules:
|
Please update to the latest version of gRPC-Go using
|
||||||
|
`go get google.golang.org/grpc`.
|
||||||
Ensure your gRPC-Go version is `require`d at the appropriate version in
|
|
||||||
the same module containing the generated `.pb.go` files. For example,
|
|
||||||
`SupportPackageIsVersion6` needs `v1.27.0`, so in your `go.mod` file:
|
|
||||||
|
|
||||||
```go
|
|
||||||
module <your module name>
|
|
||||||
|
|
||||||
require (
|
|
||||||
google.golang.org/grpc v1.27.0
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
#### If you are *not* using Go modules:
|
|
||||||
|
|
||||||
Update the `proto` package, gRPC package, and rebuild the `.proto` files:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
go get -u github.com/golang/protobuf/{proto,protoc-gen-go}
|
|
||||||
go get -u google.golang.org/grpc
|
|
||||||
protoc --go_out=plugins=grpc:. *.proto
|
|
||||||
```
|
|
||||||
|
|
||||||
### How to turn on logging
|
### How to turn on logging
|
||||||
|
|
||||||
@ -121,9 +85,11 @@ possible reasons, including:
|
|||||||
1. mis-configured transport credentials, connection failed on handshaking
|
1. mis-configured transport credentials, connection failed on handshaking
|
||||||
1. bytes disrupted, possibly by a proxy in between
|
1. bytes disrupted, possibly by a proxy in between
|
||||||
1. server shutdown
|
1. server shutdown
|
||||||
1. Keepalive parameters caused connection shutdown, for example if you have configured
|
1. Keepalive parameters caused connection shutdown, for example if you have
|
||||||
your server to terminate connections regularly to [trigger DNS lookups](https://github.com/grpc/grpc-go/issues/3170#issuecomment-552517779).
|
configured your server to terminate connections regularly to [trigger DNS
|
||||||
If this is the case, you may want to increase your [MaxConnectionAgeGrace](https://pkg.go.dev/google.golang.org/grpc/keepalive?tab=doc#ServerParameters),
|
lookups](https://github.com/grpc/grpc-go/issues/3170#issuecomment-552517779).
|
||||||
|
If this is the case, you may want to increase your
|
||||||
|
[MaxConnectionAgeGrace](https://pkg.go.dev/google.golang.org/grpc/keepalive?tab=doc#ServerParameters),
|
||||||
to allow longer RPC calls to finish.
|
to allow longer RPC calls to finish.
|
||||||
|
|
||||||
It can be tricky to debug this because the error happens on the client side but
|
It can be tricky to debug this because the error happens on the client side but
|
||||||
|
72
vendor/google.golang.org/grpc/attributes/attributes.go
generated
vendored
72
vendor/google.golang.org/grpc/attributes/attributes.go
generated
vendored
@ -25,30 +25,35 @@
|
|||||||
// later release.
|
// later release.
|
||||||
package attributes
|
package attributes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
// Attributes is an immutable struct for storing and retrieving generic
|
// Attributes is an immutable struct for storing and retrieving generic
|
||||||
// key/value pairs. Keys must be hashable, and users should define their own
|
// key/value pairs. Keys must be hashable, and users should define their own
|
||||||
// types for keys. Values should not be modified after they are added to an
|
// types for keys. Values should not be modified after they are added to an
|
||||||
// Attributes or if they were received from one. If values implement 'Equal(o
|
// Attributes or if they were received from one. If values implement 'Equal(o
|
||||||
// interface{}) bool', it will be called by (*Attributes).Equal to determine
|
// any) bool', it will be called by (*Attributes).Equal to determine whether
|
||||||
// whether two values with the same key should be considered equal.
|
// two values with the same key should be considered equal.
|
||||||
type Attributes struct {
|
type Attributes struct {
|
||||||
m map[interface{}]interface{}
|
m map[any]any
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new Attributes containing the key/value pair.
|
// New returns a new Attributes containing the key/value pair.
|
||||||
func New(key, value interface{}) *Attributes {
|
func New(key, value any) *Attributes {
|
||||||
return &Attributes{m: map[interface{}]interface{}{key: value}}
|
return &Attributes{m: map[any]any{key: value}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithValue returns a new Attributes containing the previous keys and values
|
// WithValue returns a new Attributes containing the previous keys and values
|
||||||
// and the new key/value pair. If the same key appears multiple times, the
|
// and the new key/value pair. If the same key appears multiple times, the
|
||||||
// last value overwrites all previous values for that key. To remove an
|
// last value overwrites all previous values for that key. To remove an
|
||||||
// existing key, use a nil value. value should not be modified later.
|
// existing key, use a nil value. value should not be modified later.
|
||||||
func (a *Attributes) WithValue(key, value interface{}) *Attributes {
|
func (a *Attributes) WithValue(key, value any) *Attributes {
|
||||||
if a == nil {
|
if a == nil {
|
||||||
return New(key, value)
|
return New(key, value)
|
||||||
}
|
}
|
||||||
n := &Attributes{m: make(map[interface{}]interface{}, len(a.m)+1)}
|
n := &Attributes{m: make(map[any]any, len(a.m)+1)}
|
||||||
for k, v := range a.m {
|
for k, v := range a.m {
|
||||||
n.m[k] = v
|
n.m[k] = v
|
||||||
}
|
}
|
||||||
@ -58,20 +63,19 @@ func (a *Attributes) WithValue(key, value interface{}) *Attributes {
|
|||||||
|
|
||||||
// Value returns the value associated with these attributes for key, or nil if
|
// Value returns the value associated with these attributes for key, or nil if
|
||||||
// no value is associated with key. The returned value should not be modified.
|
// no value is associated with key. The returned value should not be modified.
|
||||||
func (a *Attributes) Value(key interface{}) interface{} {
|
func (a *Attributes) Value(key any) any {
|
||||||
if a == nil {
|
if a == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return a.m[key]
|
return a.m[key]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Equal returns whether a and o are equivalent. If 'Equal(o interface{})
|
// Equal returns whether a and o are equivalent. If 'Equal(o any) bool' is
|
||||||
// bool' is implemented for a value in the attributes, it is called to
|
// implemented for a value in the attributes, it is called to determine if the
|
||||||
// determine if the value matches the one stored in the other attributes. If
|
// value matches the one stored in the other attributes. If Equal is not
|
||||||
// Equal is not implemented, standard equality is used to determine if the two
|
// implemented, standard equality is used to determine if the two values are
|
||||||
// values are equal. Note that some types (e.g. maps) aren't comparable by
|
// equal. Note that some types (e.g. maps) aren't comparable by default, so
|
||||||
// default, so they must be wrapped in a struct, or in an alias type, with Equal
|
// they must be wrapped in a struct, or in an alias type, with Equal defined.
|
||||||
// defined.
|
|
||||||
func (a *Attributes) Equal(o *Attributes) bool {
|
func (a *Attributes) Equal(o *Attributes) bool {
|
||||||
if a == nil && o == nil {
|
if a == nil && o == nil {
|
||||||
return true
|
return true
|
||||||
@ -88,7 +92,7 @@ func (a *Attributes) Equal(o *Attributes) bool {
|
|||||||
// o missing element of a
|
// o missing element of a
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if eq, ok := v.(interface{ Equal(o interface{}) bool }); ok {
|
if eq, ok := v.(interface{ Equal(o any) bool }); ok {
|
||||||
if !eq.Equal(ov) {
|
if !eq.Equal(ov) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -99,3 +103,39 @@ func (a *Attributes) Equal(o *Attributes) bool {
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// String prints the attribute map. If any key or values throughout the map
|
||||||
|
// implement fmt.Stringer, it calls that method and appends.
|
||||||
|
func (a *Attributes) String() string {
|
||||||
|
var sb strings.Builder
|
||||||
|
sb.WriteString("{")
|
||||||
|
first := true
|
||||||
|
for k, v := range a.m {
|
||||||
|
if !first {
|
||||||
|
sb.WriteString(", ")
|
||||||
|
}
|
||||||
|
sb.WriteString(fmt.Sprintf("%q: %q ", str(k), str(v)))
|
||||||
|
first = false
|
||||||
|
}
|
||||||
|
sb.WriteString("}")
|
||||||
|
return sb.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func str(x any) string {
|
||||||
|
if v, ok := x.(fmt.Stringer); ok {
|
||||||
|
return v.String()
|
||||||
|
} else if v, ok := x.(string); ok {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("<%p>", x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON helps implement the json.Marshaler interface, thereby rendering
|
||||||
|
// the Attributes correctly when printing (via pretty.JSON) structs containing
|
||||||
|
// Attributes as fields.
|
||||||
|
//
|
||||||
|
// Is it impossible to unmarshal attributes from a JSON representation and this
|
||||||
|
// method is meant only for debugging purposes.
|
||||||
|
func (a *Attributes) MarshalJSON() ([]byte, error) {
|
||||||
|
return []byte(a.String()), nil
|
||||||
|
}
|
||||||
|
49
vendor/google.golang.org/grpc/balancer/balancer.go
generated
vendored
49
vendor/google.golang.org/grpc/balancer/balancer.go
generated
vendored
@ -105,8 +105,8 @@ type SubConn interface {
|
|||||||
//
|
//
|
||||||
// This will trigger a state transition for the SubConn.
|
// This will trigger a state transition for the SubConn.
|
||||||
//
|
//
|
||||||
// Deprecated: This method is now part of the ClientConn interface and will
|
// Deprecated: this method will be removed. Create new SubConns for new
|
||||||
// eventually be removed from here.
|
// addresses instead.
|
||||||
UpdateAddresses([]resolver.Address)
|
UpdateAddresses([]resolver.Address)
|
||||||
// Connect starts the connecting for this SubConn.
|
// Connect starts the connecting for this SubConn.
|
||||||
Connect()
|
Connect()
|
||||||
@ -115,6 +115,13 @@ type SubConn interface {
|
|||||||
// creates a new one and returns it. Returns a close function which must
|
// creates a new one and returns it. Returns a close function which must
|
||||||
// be called when the Producer is no longer needed.
|
// be called when the Producer is no longer needed.
|
||||||
GetOrBuildProducer(ProducerBuilder) (p Producer, close func())
|
GetOrBuildProducer(ProducerBuilder) (p Producer, close func())
|
||||||
|
// Shutdown shuts down the SubConn gracefully. Any started RPCs will be
|
||||||
|
// allowed to complete. No future calls should be made on the SubConn.
|
||||||
|
// One final state update will be delivered to the StateListener (or
|
||||||
|
// UpdateSubConnState; deprecated) with ConnectivityState of Shutdown to
|
||||||
|
// indicate the shutdown operation. This may be delivered before
|
||||||
|
// in-progress RPCs are complete and the actual connection is closed.
|
||||||
|
Shutdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSubConnOptions contains options to create new SubConn.
|
// NewSubConnOptions contains options to create new SubConn.
|
||||||
@ -129,6 +136,11 @@ type NewSubConnOptions struct {
|
|||||||
// HealthCheckEnabled indicates whether health check service should be
|
// HealthCheckEnabled indicates whether health check service should be
|
||||||
// enabled on this SubConn
|
// enabled on this SubConn
|
||||||
HealthCheckEnabled bool
|
HealthCheckEnabled bool
|
||||||
|
// StateListener is called when the state of the subconn changes. If nil,
|
||||||
|
// Balancer.UpdateSubConnState will be called instead. Will never be
|
||||||
|
// invoked until after Connect() is called on the SubConn created with
|
||||||
|
// these options.
|
||||||
|
StateListener func(SubConnState)
|
||||||
}
|
}
|
||||||
|
|
||||||
// State contains the balancer's state relevant to the gRPC ClientConn.
|
// State contains the balancer's state relevant to the gRPC ClientConn.
|
||||||
@ -150,16 +162,24 @@ type ClientConn interface {
|
|||||||
// NewSubConn is called by balancer to create a new SubConn.
|
// NewSubConn is called by balancer to create a new SubConn.
|
||||||
// It doesn't block and wait for the connections to be established.
|
// It doesn't block and wait for the connections to be established.
|
||||||
// Behaviors of the SubConn can be controlled by options.
|
// Behaviors of the SubConn can be controlled by options.
|
||||||
|
//
|
||||||
|
// Deprecated: please be aware that in a future version, SubConns will only
|
||||||
|
// support one address per SubConn.
|
||||||
NewSubConn([]resolver.Address, NewSubConnOptions) (SubConn, error)
|
NewSubConn([]resolver.Address, NewSubConnOptions) (SubConn, error)
|
||||||
// RemoveSubConn removes the SubConn from ClientConn.
|
// RemoveSubConn removes the SubConn from ClientConn.
|
||||||
// The SubConn will be shutdown.
|
// The SubConn will be shutdown.
|
||||||
|
//
|
||||||
|
// Deprecated: use SubConn.Shutdown instead.
|
||||||
RemoveSubConn(SubConn)
|
RemoveSubConn(SubConn)
|
||||||
// UpdateAddresses updates the addresses used in the passed in SubConn.
|
// UpdateAddresses updates the addresses used in the passed in SubConn.
|
||||||
// gRPC checks if the currently connected address is still in the new list.
|
// gRPC checks if the currently connected address is still in the new list.
|
||||||
// If so, the connection will be kept. Else, the connection will be
|
// If so, the connection will be kept. Else, the connection will be
|
||||||
// gracefully closed, and a new connection will be created.
|
// gracefully closed, and a new connection will be created.
|
||||||
//
|
//
|
||||||
// This will trigger a state transition for the SubConn.
|
// This may trigger a state transition for the SubConn.
|
||||||
|
//
|
||||||
|
// Deprecated: this method will be removed. Create new SubConns for new
|
||||||
|
// addresses instead.
|
||||||
UpdateAddresses(SubConn, []resolver.Address)
|
UpdateAddresses(SubConn, []resolver.Address)
|
||||||
|
|
||||||
// UpdateState notifies gRPC that the balancer's internal state has
|
// UpdateState notifies gRPC that the balancer's internal state has
|
||||||
@ -250,7 +270,7 @@ type DoneInfo struct {
|
|||||||
// trailing metadata.
|
// trailing metadata.
|
||||||
//
|
//
|
||||||
// The only supported type now is *orca_v3.LoadReport.
|
// The only supported type now is *orca_v3.LoadReport.
|
||||||
ServerLoad interface{}
|
ServerLoad any
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -286,7 +306,7 @@ type PickResult struct {
|
|||||||
//
|
//
|
||||||
// LB policies with child policies are responsible for propagating metadata
|
// LB policies with child policies are responsible for propagating metadata
|
||||||
// injected by their children to the ClientConn, as part of Pick().
|
// injected by their children to the ClientConn, as part of Pick().
|
||||||
Metatada metadata.MD
|
Metadata metadata.MD
|
||||||
}
|
}
|
||||||
|
|
||||||
// TransientFailureError returns e. It exists for backward compatibility and
|
// TransientFailureError returns e. It exists for backward compatibility and
|
||||||
@ -343,9 +363,13 @@ type Balancer interface {
|
|||||||
ResolverError(error)
|
ResolverError(error)
|
||||||
// UpdateSubConnState is called by gRPC when the state of a SubConn
|
// UpdateSubConnState is called by gRPC when the state of a SubConn
|
||||||
// changes.
|
// changes.
|
||||||
|
//
|
||||||
|
// Deprecated: Use NewSubConnOptions.StateListener when creating the
|
||||||
|
// SubConn instead.
|
||||||
UpdateSubConnState(SubConn, SubConnState)
|
UpdateSubConnState(SubConn, SubConnState)
|
||||||
// Close closes the balancer. The balancer is not required to call
|
// Close closes the balancer. The balancer is not currently required to
|
||||||
// ClientConn.RemoveSubConn for its existing SubConns.
|
// call SubConn.Shutdown for its existing SubConns; however, this will be
|
||||||
|
// required in a future release, so it is recommended.
|
||||||
Close()
|
Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,15 +414,14 @@ var ErrBadResolverState = errors.New("bad resolver state")
|
|||||||
type ProducerBuilder interface {
|
type ProducerBuilder interface {
|
||||||
// Build creates a Producer. The first parameter is always a
|
// Build creates a Producer. The first parameter is always a
|
||||||
// grpc.ClientConnInterface (a type to allow creating RPCs/streams on the
|
// grpc.ClientConnInterface (a type to allow creating RPCs/streams on the
|
||||||
// associated SubConn), but is declared as interface{} to avoid a
|
// associated SubConn), but is declared as `any` to avoid a dependency
|
||||||
// dependency cycle. Should also return a close function that will be
|
// cycle. Should also return a close function that will be called when all
|
||||||
// called when all references to the Producer have been given up.
|
// references to the Producer have been given up.
|
||||||
Build(grpcClientConnInterface interface{}) (p Producer, close func())
|
Build(grpcClientConnInterface any) (p Producer, close func())
|
||||||
}
|
}
|
||||||
|
|
||||||
// A Producer is a type shared among potentially many consumers. It is
|
// A Producer is a type shared among potentially many consumers. It is
|
||||||
// associated with a SubConn, and an implementation will typically contain
|
// associated with a SubConn, and an implementation will typically contain
|
||||||
// other methods to provide additional functionality, e.g. configuration or
|
// other methods to provide additional functionality, e.g. configuration or
|
||||||
// subscription registration.
|
// subscription registration.
|
||||||
type Producer interface {
|
type Producer any
|
||||||
}
|
|
||||||
|
22
vendor/google.golang.org/grpc/balancer/base/balancer.go
generated
vendored
22
vendor/google.golang.org/grpc/balancer/base/balancer.go
generated
vendored
@ -105,7 +105,12 @@ func (b *baseBalancer) UpdateClientConnState(s balancer.ClientConnState) error {
|
|||||||
addrsSet.Set(a, nil)
|
addrsSet.Set(a, nil)
|
||||||
if _, ok := b.subConns.Get(a); !ok {
|
if _, ok := b.subConns.Get(a); !ok {
|
||||||
// a is a new address (not existing in b.subConns).
|
// a is a new address (not existing in b.subConns).
|
||||||
sc, err := b.cc.NewSubConn([]resolver.Address{a}, balancer.NewSubConnOptions{HealthCheckEnabled: b.config.HealthCheck})
|
var sc balancer.SubConn
|
||||||
|
opts := balancer.NewSubConnOptions{
|
||||||
|
HealthCheckEnabled: b.config.HealthCheck,
|
||||||
|
StateListener: func(scs balancer.SubConnState) { b.updateSubConnState(sc, scs) },
|
||||||
|
}
|
||||||
|
sc, err := b.cc.NewSubConn([]resolver.Address{a}, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Warningf("base.baseBalancer: failed to create new SubConn: %v", err)
|
logger.Warningf("base.baseBalancer: failed to create new SubConn: %v", err)
|
||||||
continue
|
continue
|
||||||
@ -121,10 +126,10 @@ func (b *baseBalancer) UpdateClientConnState(s balancer.ClientConnState) error {
|
|||||||
sc := sci.(balancer.SubConn)
|
sc := sci.(balancer.SubConn)
|
||||||
// a was removed by resolver.
|
// a was removed by resolver.
|
||||||
if _, ok := addrsSet.Get(a); !ok {
|
if _, ok := addrsSet.Get(a); !ok {
|
||||||
b.cc.RemoveSubConn(sc)
|
sc.Shutdown()
|
||||||
b.subConns.Delete(a)
|
b.subConns.Delete(a)
|
||||||
// Keep the state of this sc in b.scStates until sc's state becomes Shutdown.
|
// Keep the state of this sc in b.scStates until sc's state becomes Shutdown.
|
||||||
// The entry will be deleted in UpdateSubConnState.
|
// The entry will be deleted in updateSubConnState.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If resolver state contains no addresses, return an error so ClientConn
|
// If resolver state contains no addresses, return an error so ClientConn
|
||||||
@ -177,7 +182,12 @@ func (b *baseBalancer) regeneratePicker() {
|
|||||||
b.picker = b.pickerBuilder.Build(PickerBuildInfo{ReadySCs: readySCs})
|
b.picker = b.pickerBuilder.Build(PickerBuildInfo{ReadySCs: readySCs})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateSubConnState is a nop because a StateListener is always set in NewSubConn.
|
||||||
func (b *baseBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) {
|
func (b *baseBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) {
|
||||||
|
logger.Errorf("base.baseBalancer: UpdateSubConnState(%v, %+v) called unexpectedly", sc, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *baseBalancer) updateSubConnState(sc balancer.SubConn, state balancer.SubConnState) {
|
||||||
s := state.ConnectivityState
|
s := state.ConnectivityState
|
||||||
if logger.V(2) {
|
if logger.V(2) {
|
||||||
logger.Infof("base.baseBalancer: handle SubConn state change: %p, %v", sc, s)
|
logger.Infof("base.baseBalancer: handle SubConn state change: %p, %v", sc, s)
|
||||||
@ -204,8 +214,8 @@ func (b *baseBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.Su
|
|||||||
case connectivity.Idle:
|
case connectivity.Idle:
|
||||||
sc.Connect()
|
sc.Connect()
|
||||||
case connectivity.Shutdown:
|
case connectivity.Shutdown:
|
||||||
// When an address was removed by resolver, b called RemoveSubConn but
|
// When an address was removed by resolver, b called Shutdown but kept
|
||||||
// kept the sc's state in scStates. Remove state for this sc here.
|
// the sc's state in scStates. Remove state for this sc here.
|
||||||
delete(b.scStates, sc)
|
delete(b.scStates, sc)
|
||||||
case connectivity.TransientFailure:
|
case connectivity.TransientFailure:
|
||||||
// Save error to be reported via picker.
|
// Save error to be reported via picker.
|
||||||
@ -226,7 +236,7 @@ func (b *baseBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.Su
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Close is a nop because base balancer doesn't have internal state to clean up,
|
// Close is a nop because base balancer doesn't have internal state to clean up,
|
||||||
// and it doesn't need to call RemoveSubConn for the SubConns.
|
// and it doesn't need to call Shutdown for the SubConns.
|
||||||
func (b *baseBalancer) Close() {
|
func (b *baseBalancer) Close() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
477
vendor/google.golang.org/grpc/balancer_conn_wrappers.go
generated
vendored
477
vendor/google.golang.org/grpc/balancer_conn_wrappers.go
generated
vendored
@ -25,14 +25,20 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"google.golang.org/grpc/balancer"
|
"google.golang.org/grpc/balancer"
|
||||||
"google.golang.org/grpc/codes"
|
|
||||||
"google.golang.org/grpc/connectivity"
|
"google.golang.org/grpc/connectivity"
|
||||||
"google.golang.org/grpc/internal/balancer/gracefulswitch"
|
"google.golang.org/grpc/internal/balancer/gracefulswitch"
|
||||||
"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"
|
||||||
"google.golang.org/grpc/status"
|
)
|
||||||
|
|
||||||
|
type ccbMode int
|
||||||
|
|
||||||
|
const (
|
||||||
|
ccbModeActive = iota
|
||||||
|
ccbModeIdle
|
||||||
|
ccbModeClosed
|
||||||
|
ccbModeExitingIdle
|
||||||
)
|
)
|
||||||
|
|
||||||
// ccBalancerWrapper sits between the ClientConn and the Balancer.
|
// ccBalancerWrapper sits between the ClientConn and the Balancer.
|
||||||
@ -49,192 +55,89 @@ import (
|
|||||||
// It uses the gracefulswitch.Balancer internally to ensure that balancer
|
// It uses the gracefulswitch.Balancer internally to ensure that balancer
|
||||||
// switches happen in a graceful manner.
|
// switches happen in a graceful manner.
|
||||||
type ccBalancerWrapper struct {
|
type ccBalancerWrapper struct {
|
||||||
|
// The following fields are initialized when the wrapper is created and are
|
||||||
|
// read-only afterwards, and therefore can be accessed without a mutex.
|
||||||
cc *ClientConn
|
cc *ClientConn
|
||||||
|
opts balancer.BuildOptions
|
||||||
|
|
||||||
// Since these fields are accessed only from handleXxx() methods which are
|
// Outgoing (gRPC --> balancer) calls are guaranteed to execute in a
|
||||||
// synchronized by the watcher goroutine, we do not need a mutex to protect
|
// mutually exclusive manner as they are scheduled in the serializer. Fields
|
||||||
// these fields.
|
// accessed *only* in these serializer callbacks, can therefore be accessed
|
||||||
|
// without a mutex.
|
||||||
balancer *gracefulswitch.Balancer
|
balancer *gracefulswitch.Balancer
|
||||||
curBalancerName string
|
curBalancerName string
|
||||||
|
|
||||||
updateCh *buffer.Unbounded // Updates written on this channel are processed by watcher().
|
// mu guards access to the below fields. Access to the serializer and its
|
||||||
resultCh *buffer.Unbounded // Results of calls to UpdateClientConnState() are pushed here.
|
// cancel function needs to be mutex protected because they are overwritten
|
||||||
closed *grpcsync.Event // Indicates if close has been called.
|
// when the wrapper exits idle mode.
|
||||||
done *grpcsync.Event // Indicates if close has completed its work.
|
mu sync.Mutex
|
||||||
|
serializer *grpcsync.CallbackSerializer // To serialize all outoing calls.
|
||||||
|
serializerCancel context.CancelFunc // To close the seralizer at close/enterIdle time.
|
||||||
|
mode ccbMode // Tracks the current mode of the wrapper.
|
||||||
}
|
}
|
||||||
|
|
||||||
// newCCBalancerWrapper creates a new balancer wrapper. The underlying balancer
|
// newCCBalancerWrapper creates a new balancer wrapper. The underlying balancer
|
||||||
// is not created until the switchTo() method is invoked.
|
// is not created until the switchTo() method is invoked.
|
||||||
func newCCBalancerWrapper(cc *ClientConn, bopts balancer.BuildOptions) *ccBalancerWrapper {
|
func newCCBalancerWrapper(cc *ClientConn, bopts balancer.BuildOptions) *ccBalancerWrapper {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
ccb := &ccBalancerWrapper{
|
ccb := &ccBalancerWrapper{
|
||||||
cc: cc,
|
cc: cc,
|
||||||
updateCh: buffer.NewUnbounded(),
|
opts: bopts,
|
||||||
resultCh: buffer.NewUnbounded(),
|
serializer: grpcsync.NewCallbackSerializer(ctx),
|
||||||
closed: grpcsync.NewEvent(),
|
serializerCancel: cancel,
|
||||||
done: grpcsync.NewEvent(),
|
|
||||||
}
|
}
|
||||||
go ccb.watcher()
|
|
||||||
ccb.balancer = gracefulswitch.NewBalancer(ccb, bopts)
|
ccb.balancer = gracefulswitch.NewBalancer(ccb, bopts)
|
||||||
return ccb
|
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 {
|
|
||||||
sc balancer.SubConn
|
|
||||||
state connectivity.State
|
|
||||||
err error
|
|
||||||
}
|
|
||||||
|
|
||||||
type exitIdleUpdate struct{}
|
|
||||||
|
|
||||||
type resolverErrorUpdate struct {
|
|
||||||
err error
|
|
||||||
}
|
|
||||||
|
|
||||||
type switchToUpdate struct {
|
|
||||||
name string
|
|
||||||
}
|
|
||||||
|
|
||||||
type subConnUpdate struct {
|
|
||||||
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() {
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case u := <-ccb.updateCh.Get():
|
|
||||||
ccb.updateCh.Load()
|
|
||||||
if ccb.closed.HasFired() {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
switch update := u.(type) {
|
|
||||||
case *ccStateUpdate:
|
|
||||||
ccb.handleClientConnStateChange(update.ccs)
|
|
||||||
case *scStateUpdate:
|
|
||||||
ccb.handleSubConnStateChange(update)
|
|
||||||
case *exitIdleUpdate:
|
|
||||||
ccb.handleExitIdle()
|
|
||||||
case *resolverErrorUpdate:
|
|
||||||
ccb.handleResolverError(update.err)
|
|
||||||
case *switchToUpdate:
|
|
||||||
ccb.handleSwitchTo(update.name)
|
|
||||||
case *subConnUpdate:
|
|
||||||
ccb.handleRemoveSubConn(update.acbw)
|
|
||||||
default:
|
|
||||||
logger.Errorf("ccBalancerWrapper.watcher: unknown update %+v, type %T", update, update)
|
|
||||||
}
|
|
||||||
case <-ccb.closed.Done():
|
|
||||||
}
|
|
||||||
|
|
||||||
if ccb.closed.HasFired() {
|
|
||||||
ccb.handleClose()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// updateClientConnState is invoked by grpc to push a ClientConnState update to
|
// updateClientConnState is invoked by grpc to push a ClientConnState update to
|
||||||
// the underlying balancer.
|
// the underlying balancer.
|
||||||
//
|
|
||||||
// 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 {
|
func (ccb *ccBalancerWrapper) updateClientConnState(ccs *balancer.ClientConnState) error {
|
||||||
ccb.updateCh.Put(&ccStateUpdate{ccs: ccs})
|
ccb.mu.Lock()
|
||||||
|
errCh := make(chan error, 1)
|
||||||
|
// Here and everywhere else where Schedule() is called, it is done with the
|
||||||
|
// lock held. But the lock guards only the scheduling part. The actual
|
||||||
|
// callback is called asynchronously without the lock being held.
|
||||||
|
ok := ccb.serializer.Schedule(func(_ context.Context) {
|
||||||
|
errCh <- ccb.balancer.UpdateClientConnState(*ccs)
|
||||||
|
})
|
||||||
|
if !ok {
|
||||||
|
// If we are unable to schedule a function with the serializer, it
|
||||||
|
// indicates that it has been closed. A serializer is only closed when
|
||||||
|
// the wrapper is closed or is in idle.
|
||||||
|
ccb.mu.Unlock()
|
||||||
|
return fmt.Errorf("grpc: cannot send state update to a closed or idle balancer")
|
||||||
|
}
|
||||||
|
ccb.mu.Unlock()
|
||||||
|
|
||||||
var res interface{}
|
// We get here only if the above call to Schedule succeeds, in which case it
|
||||||
select {
|
// is guaranteed that the scheduled function will run. Therefore it is safe
|
||||||
case res = <-ccb.resultCh.Get():
|
// to block on this channel.
|
||||||
ccb.resultCh.Load()
|
err := <-errCh
|
||||||
case <-ccb.closed.Done():
|
if logger.V(2) && err != nil {
|
||||||
// Return early if the balancer wrapper is closed while we are waiting for
|
logger.Infof("error from balancer.UpdateClientConnState: %v", err)
|
||||||
// the underlying balancer to process a ClientConnState update.
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
// If the returned error is nil, attempting to type assert to error leads to
|
return err
|
||||||
// panic. So, this needs to handled separately.
|
|
||||||
if res == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return res.(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
|
// updateSubConnState is invoked by grpc to push a subConn state update to the
|
||||||
// underlying balancer.
|
// underlying balancer.
|
||||||
func (ccb *ccBalancerWrapper) updateSubConnState(sc balancer.SubConn, s connectivity.State, err error) {
|
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
|
ccb.mu.Lock()
|
||||||
// the new addresses, the old ac will be tearDown() and a new ac will be
|
ccb.serializer.Schedule(func(_ context.Context) {
|
||||||
// created. tearDown() generates a state change with Shutdown state, we
|
// Even though it is optional for balancers, gracefulswitch ensures
|
||||||
// don't want the balancer to receive this state change. So before
|
// opts.StateListener is set, so this cannot ever be nil.
|
||||||
// tearDown() on the old ac, ac.acbw (acWrapper) will be set to nil, and
|
sc.(*acBalancerWrapper).stateListener(balancer.SubConnState{ConnectivityState: s, ConnectionError: err})
|
||||||
// this function will be called with (nil, Shutdown). We don't need to call
|
|
||||||
// balancer method in this case.
|
|
||||||
if sc == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ccb.updateCh.Put(&scStateUpdate{
|
|
||||||
sc: sc,
|
|
||||||
state: s,
|
|
||||||
err: err,
|
|
||||||
})
|
})
|
||||||
}
|
ccb.mu.Unlock()
|
||||||
|
|
||||||
// handleSubConnStateChange handles a SubConnState update from the update
|
|
||||||
// channel and invokes the appropriate method on the underlying balancer.
|
|
||||||
func (ccb *ccBalancerWrapper) handleSubConnStateChange(update *scStateUpdate) {
|
|
||||||
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.updateCh.Put(&resolverErrorUpdate{err: err})
|
ccb.mu.Lock()
|
||||||
}
|
ccb.serializer.Schedule(func(_ context.Context) {
|
||||||
|
|
||||||
func (ccb *ccBalancerWrapper) handleResolverError(err error) {
|
|
||||||
ccb.balancer.ResolverError(err)
|
ccb.balancer.ResolverError(err)
|
||||||
|
})
|
||||||
|
ccb.mu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// switchTo is invoked by grpc to instruct the balancer wrapper to switch to the
|
// switchTo is invoked by grpc to instruct the balancer wrapper to switch to the
|
||||||
@ -248,24 +151,27 @@ func (ccb *ccBalancerWrapper) handleResolverError(err error) {
|
|||||||
// the ccBalancerWrapper keeps track of the current LB policy name, and skips
|
// the ccBalancerWrapper keeps track of the current LB policy name, and skips
|
||||||
// the graceful balancer switching process if the name does not change.
|
// the graceful balancer switching process if the name does not change.
|
||||||
func (ccb *ccBalancerWrapper) switchTo(name string) {
|
func (ccb *ccBalancerWrapper) switchTo(name string) {
|
||||||
ccb.updateCh.Put(&switchToUpdate{name: name})
|
ccb.mu.Lock()
|
||||||
}
|
ccb.serializer.Schedule(func(_ context.Context) {
|
||||||
|
// TODO: Other languages use case-sensitive balancer registries. We should
|
||||||
// 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.
|
// switch as well. See: https://github.com/grpc/grpc-go/issues/5288.
|
||||||
if strings.EqualFold(ccb.curBalancerName, name) {
|
if strings.EqualFold(ccb.curBalancerName, name) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
ccb.buildLoadBalancingPolicy(name)
|
||||||
|
})
|
||||||
|
ccb.mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Ensure that name is a registered LB policy when we get here.
|
// buildLoadBalancingPolicy performs the following:
|
||||||
// We currently only validate the `loadBalancingConfig` field. We need to do
|
// - retrieve a balancer builder for the given name. Use the default LB
|
||||||
// the same for the `loadBalancingPolicy` field and reject the service config
|
// policy, pick_first, if no LB policy with name is found in the registry.
|
||||||
// if the specified policy is not registered.
|
// - instruct the gracefulswitch balancer to switch to the above builder. This
|
||||||
|
// will actually build the new balancer.
|
||||||
|
// - update the `curBalancerName` field
|
||||||
|
//
|
||||||
|
// Must be called from a serializer callback.
|
||||||
|
func (ccb *ccBalancerWrapper) buildLoadBalancingPolicy(name string) {
|
||||||
builder := balancer.Get(name)
|
builder := balancer.Get(name)
|
||||||
if builder == nil {
|
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)
|
channelz.Warningf(logger, ccb.cc.channelzID, "Channel switches to new LB policy %q, since the specified LB policy %q was not registered", PickFirstBalancerName, name)
|
||||||
@ -281,26 +187,112 @@ func (ccb *ccBalancerWrapper) handleSwitchTo(name string) {
|
|||||||
ccb.curBalancerName = builder.Name()
|
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() {
|
func (ccb *ccBalancerWrapper) close() {
|
||||||
ccb.closed.Fire()
|
channelz.Info(logger, ccb.cc.channelzID, "ccBalancerWrapper: closing")
|
||||||
<-ccb.done.Done()
|
ccb.closeBalancer(ccbModeClosed)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ccb *ccBalancerWrapper) handleClose() {
|
// enterIdleMode is invoked by grpc when the channel enters idle mode upon
|
||||||
ccb.balancer.Close()
|
// expiry of idle_timeout. This call blocks until the balancer is closed.
|
||||||
ccb.done.Fire()
|
func (ccb *ccBalancerWrapper) enterIdleMode() {
|
||||||
|
channelz.Info(logger, ccb.cc.channelzID, "ccBalancerWrapper: entering idle mode")
|
||||||
|
ccb.closeBalancer(ccbModeIdle)
|
||||||
|
}
|
||||||
|
|
||||||
|
// closeBalancer is invoked when the channel is being closed or when it enters
|
||||||
|
// idle mode upon expiry of idle_timeout.
|
||||||
|
func (ccb *ccBalancerWrapper) closeBalancer(m ccbMode) {
|
||||||
|
ccb.mu.Lock()
|
||||||
|
if ccb.mode == ccbModeClosed || ccb.mode == ccbModeIdle {
|
||||||
|
ccb.mu.Unlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ccb.mode = m
|
||||||
|
done := ccb.serializer.Done()
|
||||||
|
b := ccb.balancer
|
||||||
|
ok := ccb.serializer.Schedule(func(_ context.Context) {
|
||||||
|
// Close the serializer to ensure that no more calls from gRPC are sent
|
||||||
|
// to the balancer.
|
||||||
|
ccb.serializerCancel()
|
||||||
|
// Empty the current balancer name because we don't have a balancer
|
||||||
|
// anymore and also so that we act on the next call to switchTo by
|
||||||
|
// creating a new balancer specified by the new resolver.
|
||||||
|
ccb.curBalancerName = ""
|
||||||
|
})
|
||||||
|
if !ok {
|
||||||
|
ccb.mu.Unlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ccb.mu.Unlock()
|
||||||
|
|
||||||
|
// Give enqueued callbacks a chance to finish before closing the balancer.
|
||||||
|
<-done
|
||||||
|
b.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
// exitIdleMode is invoked by grpc when the channel exits idle mode either
|
||||||
|
// because of an RPC or because of an invocation of the Connect() API. This
|
||||||
|
// recreates the balancer that was closed previously when entering idle mode.
|
||||||
|
//
|
||||||
|
// If the channel is not in idle mode, we know for a fact that we are here as a
|
||||||
|
// result of the user calling the Connect() method on the ClientConn. In this
|
||||||
|
// case, we can simply forward the call to the underlying balancer, instructing
|
||||||
|
// it to reconnect to the backends.
|
||||||
|
func (ccb *ccBalancerWrapper) exitIdleMode() {
|
||||||
|
ccb.mu.Lock()
|
||||||
|
if ccb.mode == ccbModeClosed {
|
||||||
|
// Request to exit idle is a no-op when wrapper is already closed.
|
||||||
|
ccb.mu.Unlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if ccb.mode == ccbModeIdle {
|
||||||
|
// Recreate the serializer which was closed when we entered idle.
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
ccb.serializer = grpcsync.NewCallbackSerializer(ctx)
|
||||||
|
ccb.serializerCancel = cancel
|
||||||
|
}
|
||||||
|
|
||||||
|
// The ClientConn guarantees that mutual exclusion between close() and
|
||||||
|
// exitIdleMode(), and since we just created a new serializer, we can be
|
||||||
|
// sure that the below function will be scheduled.
|
||||||
|
done := make(chan struct{})
|
||||||
|
ccb.serializer.Schedule(func(_ context.Context) {
|
||||||
|
defer close(done)
|
||||||
|
|
||||||
|
ccb.mu.Lock()
|
||||||
|
defer ccb.mu.Unlock()
|
||||||
|
|
||||||
|
if ccb.mode != ccbModeIdle {
|
||||||
|
ccb.balancer.ExitIdle()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gracefulswitch balancer does not support a switchTo operation after
|
||||||
|
// being closed. Hence we need to create a new one here.
|
||||||
|
ccb.balancer = gracefulswitch.NewBalancer(ccb, ccb.opts)
|
||||||
|
ccb.mode = ccbModeActive
|
||||||
|
channelz.Info(logger, ccb.cc.channelzID, "ccBalancerWrapper: exiting idle mode")
|
||||||
|
|
||||||
|
})
|
||||||
|
ccb.mu.Unlock()
|
||||||
|
|
||||||
|
<-done
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ccb *ccBalancerWrapper) isIdleOrClosed() bool {
|
||||||
|
ccb.mu.Lock()
|
||||||
|
defer ccb.mu.Unlock()
|
||||||
|
return ccb.mode == ccbModeIdle || ccb.mode == ccbModeClosed
|
||||||
}
|
}
|
||||||
|
|
||||||
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 ccb.isIdleOrClosed() {
|
||||||
|
return nil, fmt.Errorf("grpc: cannot create SubConn when balancer is closed or idle")
|
||||||
|
}
|
||||||
|
|
||||||
|
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")
|
||||||
}
|
}
|
||||||
ac, err := ccb.cc.newAddrConn(addrs, opts)
|
ac, err := ccb.cc.newAddrConn(addrs, opts)
|
||||||
@ -308,32 +300,26 @@ func (ccb *ccBalancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer
|
|||||||
channelz.Warningf(logger, ccb.cc.channelzID, "acBalancerWrapper: NewSubConn: failed to newAddrConn: %v", err)
|
channelz.Warningf(logger, ccb.cc.channelzID, "acBalancerWrapper: NewSubConn: failed to newAddrConn: %v", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
acbw := &acBalancerWrapper{ac: ac, producers: make(map[balancer.ProducerBuilder]*refCountedProducer)}
|
acbw := &acBalancerWrapper{
|
||||||
acbw.ac.mu.Lock()
|
ccb: ccb,
|
||||||
|
ac: ac,
|
||||||
|
producers: make(map[balancer.ProducerBuilder]*refCountedProducer),
|
||||||
|
stateListener: opts.StateListener,
|
||||||
|
}
|
||||||
ac.acbw = acbw
|
ac.acbw = acbw
|
||||||
acbw.ac.mu.Unlock()
|
|
||||||
return acbw, nil
|
return acbw, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ccb *ccBalancerWrapper) RemoveSubConn(sc balancer.SubConn) {
|
func (ccb *ccBalancerWrapper) RemoveSubConn(sc balancer.SubConn) {
|
||||||
// Before we switched the ccBalancerWrapper to use gracefulswitch.Balancer, it
|
// The graceful switch balancer will never call this.
|
||||||
// was required to handle the RemoveSubConn() method asynchronously by pushing
|
logger.Errorf("ccb RemoveSubConn(%v) called unexpectedly, sc")
|
||||||
// the update onto the update channel. This was done to avoid a deadlock as
|
|
||||||
// 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) {
|
||||||
|
if ccb.isIdleOrClosed() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
acbw, ok := sc.(*acBalancerWrapper)
|
acbw, ok := sc.(*acBalancerWrapper)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
@ -342,6 +328,10 @@ func (ccb *ccBalancerWrapper) UpdateAddresses(sc balancer.SubConn, addrs []resol
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ccb *ccBalancerWrapper) UpdateState(s balancer.State) {
|
func (ccb *ccBalancerWrapper) UpdateState(s balancer.State) {
|
||||||
|
if ccb.isIdleOrClosed() {
|
||||||
|
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
|
||||||
@ -352,6 +342,10 @@ func (ccb *ccBalancerWrapper) UpdateState(s balancer.State) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ccb *ccBalancerWrapper) ResolveNow(o resolver.ResolveNowOptions) {
|
func (ccb *ccBalancerWrapper) ResolveNow(o resolver.ResolveNowOptions) {
|
||||||
|
if ccb.isIdleOrClosed() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
ccb.cc.resolveNow(o)
|
ccb.cc.resolveNow(o)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,78 +356,57 @@ func (ccb *ccBalancerWrapper) Target() string {
|
|||||||
// acBalancerWrapper is a wrapper on top of ac for balancers.
|
// acBalancerWrapper is a wrapper on top of ac for balancers.
|
||||||
// It implements balancer.SubConn interface.
|
// It implements balancer.SubConn interface.
|
||||||
type acBalancerWrapper struct {
|
type acBalancerWrapper struct {
|
||||||
|
ac *addrConn // read-only
|
||||||
|
ccb *ccBalancerWrapper // read-only
|
||||||
|
stateListener func(balancer.SubConnState)
|
||||||
|
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
ac *addrConn
|
|
||||||
producers map[balancer.ProducerBuilder]*refCountedProducer
|
producers map[balancer.ProducerBuilder]*refCountedProducer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (acbw *acBalancerWrapper) String() string {
|
||||||
|
return fmt.Sprintf("SubConn(id:%d)", acbw.ac.channelzID.Int())
|
||||||
|
}
|
||||||
|
|
||||||
func (acbw *acBalancerWrapper) UpdateAddresses(addrs []resolver.Address) {
|
func (acbw *acBalancerWrapper) UpdateAddresses(addrs []resolver.Address) {
|
||||||
acbw.mu.Lock()
|
acbw.ac.updateAddrs(addrs)
|
||||||
defer acbw.mu.Unlock()
|
|
||||||
if len(addrs) <= 0 {
|
|
||||||
acbw.ac.cc.removeAddrConn(acbw.ac, errConnDrain)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !acbw.ac.tryUpdateAddrs(addrs) {
|
|
||||||
cc := acbw.ac.cc
|
|
||||||
opts := acbw.ac.scopts
|
|
||||||
acbw.ac.mu.Lock()
|
|
||||||
// Set old ac.acbw to nil so the Shutdown state update will be ignored
|
|
||||||
// by balancer.
|
|
||||||
//
|
|
||||||
// TODO(bar) the state transition could be wrong when tearDown() old ac
|
|
||||||
// and creating new ac, fix the transition.
|
|
||||||
acbw.ac.acbw = nil
|
|
||||||
acbw.ac.mu.Unlock()
|
|
||||||
acState := acbw.ac.getState()
|
|
||||||
acbw.ac.cc.removeAddrConn(acbw.ac, errConnDrain)
|
|
||||||
|
|
||||||
if acState == connectivity.Shutdown {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
newAC, err := cc.newAddrConn(addrs, opts)
|
|
||||||
if err != nil {
|
|
||||||
channelz.Warningf(logger, acbw.ac.channelzID, "acBalancerWrapper: UpdateAddresses: failed to newAddrConn: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
acbw.ac = newAC
|
|
||||||
newAC.mu.Lock()
|
|
||||||
newAC.acbw = acbw
|
|
||||||
newAC.mu.Unlock()
|
|
||||||
if acState != connectivity.Idle {
|
|
||||||
go newAC.connect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (acbw *acBalancerWrapper) Connect() {
|
func (acbw *acBalancerWrapper) Connect() {
|
||||||
acbw.mu.Lock()
|
|
||||||
defer acbw.mu.Unlock()
|
|
||||||
go acbw.ac.connect()
|
go acbw.ac.connect()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (acbw *acBalancerWrapper) getAddrConn() *addrConn {
|
func (acbw *acBalancerWrapper) Shutdown() {
|
||||||
acbw.mu.Lock()
|
ccb := acbw.ccb
|
||||||
defer acbw.mu.Unlock()
|
if ccb.isIdleOrClosed() {
|
||||||
return acbw.ac
|
// It it safe to ignore this call when the balancer is closed or in idle
|
||||||
|
// because the ClientConn takes care of closing the connections.
|
||||||
|
//
|
||||||
|
// Not returning early from here when the balancer is closed or in idle
|
||||||
|
// leads to a deadlock though, because of the following sequence of
|
||||||
|
// calls when holding cc.mu:
|
||||||
|
// cc.exitIdleMode --> ccb.enterIdleMode --> gsw.Close -->
|
||||||
|
// ccb.RemoveAddrConn --> cc.removeAddrConn
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var errSubConnNotReady = status.Error(codes.Unavailable, "SubConn not currently connected")
|
ccb.cc.removeAddrConn(acbw.ac, errConnDrain)
|
||||||
|
}
|
||||||
|
|
||||||
// NewStream begins a streaming RPC on the addrConn. If the addrConn is not
|
// NewStream begins a streaming RPC on the addrConn. If the addrConn is not
|
||||||
// ready, returns errSubConnNotReady.
|
// ready, blocks until it is or ctx expires. Returns an error when the context
|
||||||
|
// expires or the addrConn is shut down.
|
||||||
func (acbw *acBalancerWrapper) NewStream(ctx context.Context, desc *StreamDesc, method string, opts ...CallOption) (ClientStream, error) {
|
func (acbw *acBalancerWrapper) NewStream(ctx context.Context, desc *StreamDesc, method string, opts ...CallOption) (ClientStream, error) {
|
||||||
transport := acbw.ac.getReadyTransport()
|
transport, err := acbw.ac.getTransport(ctx)
|
||||||
if transport == nil {
|
if err != nil {
|
||||||
return nil, errSubConnNotReady
|
return nil, err
|
||||||
}
|
}
|
||||||
return newNonRetryClientStream(ctx, desc, method, transport, acbw.ac, opts...)
|
return newNonRetryClientStream(ctx, desc, method, transport, acbw.ac, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoke performs a unary RPC. If the addrConn is not ready, returns
|
// Invoke performs a unary RPC. If the addrConn is not ready, returns
|
||||||
// errSubConnNotReady.
|
// errSubConnNotReady.
|
||||||
func (acbw *acBalancerWrapper) Invoke(ctx context.Context, method string, args interface{}, reply interface{}, opts ...CallOption) error {
|
func (acbw *acBalancerWrapper) Invoke(ctx context.Context, method string, args any, reply any, opts ...CallOption) error {
|
||||||
cs, err := acbw.NewStream(ctx, unaryStreamDesc, method, opts...)
|
cs, err := acbw.NewStream(ctx, unaryStreamDesc, method, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
4
vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go
generated
vendored
4
vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go
generated
vendored
@ -18,8 +18,8 @@
|
|||||||
|
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.28.1
|
// protoc-gen-go v1.31.0
|
||||||
// protoc v3.14.0
|
// protoc v4.22.0
|
||||||
// source: grpc/binlog/v1/binarylog.proto
|
// source: grpc/binlog/v1/binarylog.proto
|
||||||
|
|
||||||
package grpc_binarylog_v1
|
package grpc_binarylog_v1
|
||||||
|
6
vendor/google.golang.org/grpc/call.go
generated
vendored
6
vendor/google.golang.org/grpc/call.go
generated
vendored
@ -26,7 +26,7 @@ import (
|
|||||||
// received. This is typically called by generated code.
|
// received. This is typically called by generated code.
|
||||||
//
|
//
|
||||||
// All errors returned by Invoke are compatible with the status package.
|
// All errors returned by Invoke are compatible with the status package.
|
||||||
func (cc *ClientConn) Invoke(ctx context.Context, method string, args, reply interface{}, opts ...CallOption) error {
|
func (cc *ClientConn) Invoke(ctx context.Context, method string, args, reply any, opts ...CallOption) error {
|
||||||
// allow interceptor to see all applicable call options, which means those
|
// allow interceptor to see all applicable call options, which means those
|
||||||
// configured as defaults from dial option as well as per-call options
|
// configured as defaults from dial option as well as per-call options
|
||||||
opts = combine(cc.dopts.callOptions, opts)
|
opts = combine(cc.dopts.callOptions, opts)
|
||||||
@ -56,13 +56,13 @@ func combine(o1 []CallOption, o2 []CallOption) []CallOption {
|
|||||||
// received. This is typically called by generated code.
|
// received. This is typically called by generated code.
|
||||||
//
|
//
|
||||||
// DEPRECATED: Use ClientConn.Invoke instead.
|
// DEPRECATED: Use ClientConn.Invoke instead.
|
||||||
func Invoke(ctx context.Context, method string, args, reply interface{}, cc *ClientConn, opts ...CallOption) error {
|
func Invoke(ctx context.Context, method string, args, reply any, cc *ClientConn, opts ...CallOption) error {
|
||||||
return cc.Invoke(ctx, method, args, reply, opts...)
|
return cc.Invoke(ctx, method, args, reply, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
var unaryStreamDesc = &StreamDesc{ServerStreams: false, ClientStreams: false}
|
var unaryStreamDesc = &StreamDesc{ServerStreams: false, ClientStreams: false}
|
||||||
|
|
||||||
func invoke(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, opts ...CallOption) error {
|
func invoke(ctx context.Context, method string, req, reply any, cc *ClientConn, opts ...CallOption) error {
|
||||||
cs, err := newClientStream(ctx, unaryStreamDesc, cc, method, opts...)
|
cs, err := newClientStream(ctx, unaryStreamDesc, cc, method, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
805
vendor/google.golang.org/grpc/clientconn.go
generated
vendored
805
vendor/google.golang.org/grpc/clientconn.go
generated
vendored
File diff suppressed because it is too large
Load Diff
8
vendor/google.golang.org/grpc/codec.go
generated
vendored
8
vendor/google.golang.org/grpc/codec.go
generated
vendored
@ -27,8 +27,8 @@ import (
|
|||||||
// omits the name/string, which vary between the two and are not needed for
|
// omits the name/string, which vary between the two and are not needed for
|
||||||
// anything besides the registry in the encoding package.
|
// anything besides the registry in the encoding package.
|
||||||
type baseCodec interface {
|
type baseCodec interface {
|
||||||
Marshal(v interface{}) ([]byte, error)
|
Marshal(v any) ([]byte, error)
|
||||||
Unmarshal(data []byte, v interface{}) error
|
Unmarshal(data []byte, v any) error
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ baseCodec = Codec(nil)
|
var _ baseCodec = Codec(nil)
|
||||||
@ -41,9 +41,9 @@ var _ baseCodec = encoding.Codec(nil)
|
|||||||
// Deprecated: use encoding.Codec instead.
|
// Deprecated: use encoding.Codec instead.
|
||||||
type Codec interface {
|
type Codec interface {
|
||||||
// Marshal returns the wire format of v.
|
// Marshal returns the wire format of v.
|
||||||
Marshal(v interface{}) ([]byte, error)
|
Marshal(v any) ([]byte, error)
|
||||||
// Unmarshal parses the wire format into v.
|
// Unmarshal parses the wire format into v.
|
||||||
Unmarshal(data []byte, v interface{}) error
|
Unmarshal(data []byte, v any) error
|
||||||
// String returns the name of the Codec implementation. This is unused by
|
// String returns the name of the Codec implementation. This is unused by
|
||||||
// gRPC.
|
// gRPC.
|
||||||
String() string
|
String() string
|
||||||
|
51
vendor/google.golang.org/grpc/codes/code_string.go
generated
vendored
51
vendor/google.golang.org/grpc/codes/code_string.go
generated
vendored
@ -18,7 +18,15 @@
|
|||||||
|
|
||||||
package codes
|
package codes
|
||||||
|
|
||||||
import "strconv"
|
import (
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"google.golang.org/grpc/internal"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
internal.CanonicalString = canonicalString
|
||||||
|
}
|
||||||
|
|
||||||
func (c Code) String() string {
|
func (c Code) String() string {
|
||||||
switch c {
|
switch c {
|
||||||
@ -60,3 +68,44 @@ func (c Code) String() string {
|
|||||||
return "Code(" + strconv.FormatInt(int64(c), 10) + ")"
|
return "Code(" + strconv.FormatInt(int64(c), 10) + ")"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func canonicalString(c Code) string {
|
||||||
|
switch c {
|
||||||
|
case OK:
|
||||||
|
return "OK"
|
||||||
|
case Canceled:
|
||||||
|
return "CANCELLED"
|
||||||
|
case Unknown:
|
||||||
|
return "UNKNOWN"
|
||||||
|
case InvalidArgument:
|
||||||
|
return "INVALID_ARGUMENT"
|
||||||
|
case DeadlineExceeded:
|
||||||
|
return "DEADLINE_EXCEEDED"
|
||||||
|
case NotFound:
|
||||||
|
return "NOT_FOUND"
|
||||||
|
case AlreadyExists:
|
||||||
|
return "ALREADY_EXISTS"
|
||||||
|
case PermissionDenied:
|
||||||
|
return "PERMISSION_DENIED"
|
||||||
|
case ResourceExhausted:
|
||||||
|
return "RESOURCE_EXHAUSTED"
|
||||||
|
case FailedPrecondition:
|
||||||
|
return "FAILED_PRECONDITION"
|
||||||
|
case Aborted:
|
||||||
|
return "ABORTED"
|
||||||
|
case OutOfRange:
|
||||||
|
return "OUT_OF_RANGE"
|
||||||
|
case Unimplemented:
|
||||||
|
return "UNIMPLEMENTED"
|
||||||
|
case Internal:
|
||||||
|
return "INTERNAL"
|
||||||
|
case Unavailable:
|
||||||
|
return "UNAVAILABLE"
|
||||||
|
case DataLoss:
|
||||||
|
return "DATA_LOSS"
|
||||||
|
case Unauthenticated:
|
||||||
|
return "UNAUTHENTICATED"
|
||||||
|
default:
|
||||||
|
return "CODE(" + strconv.FormatInt(int64(c), 10) + ")"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
84
vendor/google.golang.org/grpc/dialoptions.go
generated
vendored
84
vendor/google.golang.org/grpc/dialoptions.go
generated
vendored
@ -38,13 +38,14 @@ import (
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
internal.AddGlobalDialOptions = func(opt ...DialOption) {
|
internal.AddGlobalDialOptions = func(opt ...DialOption) {
|
||||||
extraDialOptions = append(extraDialOptions, opt...)
|
globalDialOptions = append(globalDialOptions, opt...)
|
||||||
}
|
}
|
||||||
internal.ClearGlobalDialOptions = func() {
|
internal.ClearGlobalDialOptions = func() {
|
||||||
extraDialOptions = nil
|
globalDialOptions = nil
|
||||||
}
|
}
|
||||||
internal.WithBinaryLogger = withBinaryLogger
|
internal.WithBinaryLogger = withBinaryLogger
|
||||||
internal.JoinDialOptions = newJoinDialOption
|
internal.JoinDialOptions = newJoinDialOption
|
||||||
|
internal.DisableGlobalDialOptions = newDisableGlobalDialOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
// dialOptions configure a Dial call. dialOptions are set by the DialOption
|
// dialOptions configure a Dial call. dialOptions are set by the DialOption
|
||||||
@ -76,6 +77,8 @@ type dialOptions struct {
|
|||||||
defaultServiceConfig *ServiceConfig // defaultServiceConfig is parsed from defaultServiceConfigRawJSON.
|
defaultServiceConfig *ServiceConfig // defaultServiceConfig is parsed from defaultServiceConfigRawJSON.
|
||||||
defaultServiceConfigRawJSON *string
|
defaultServiceConfigRawJSON *string
|
||||||
resolvers []resolver.Builder
|
resolvers []resolver.Builder
|
||||||
|
idleTimeout time.Duration
|
||||||
|
recvBufferPool SharedBufferPool
|
||||||
}
|
}
|
||||||
|
|
||||||
// DialOption configures how we set up the connection.
|
// DialOption configures how we set up the connection.
|
||||||
@ -83,7 +86,7 @@ type DialOption interface {
|
|||||||
apply(*dialOptions)
|
apply(*dialOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
var extraDialOptions []DialOption
|
var globalDialOptions []DialOption
|
||||||
|
|
||||||
// EmptyDialOption does not alter the dial configuration. It can be embedded in
|
// EmptyDialOption does not alter the dial configuration. It can be embedded in
|
||||||
// another structure to build custom dial options.
|
// another structure to build custom dial options.
|
||||||
@ -96,6 +99,16 @@ type EmptyDialOption struct{}
|
|||||||
|
|
||||||
func (EmptyDialOption) apply(*dialOptions) {}
|
func (EmptyDialOption) apply(*dialOptions) {}
|
||||||
|
|
||||||
|
type disableGlobalDialOptions struct{}
|
||||||
|
|
||||||
|
func (disableGlobalDialOptions) apply(*dialOptions) {}
|
||||||
|
|
||||||
|
// newDisableGlobalDialOptions returns a DialOption that prevents the ClientConn
|
||||||
|
// from applying the global DialOptions (set via AddGlobalDialOptions).
|
||||||
|
func newDisableGlobalDialOptions() DialOption {
|
||||||
|
return &disableGlobalDialOptions{}
|
||||||
|
}
|
||||||
|
|
||||||
// funcDialOption wraps a function that modifies dialOptions into an
|
// funcDialOption wraps a function that modifies dialOptions into an
|
||||||
// implementation of the DialOption interface.
|
// implementation of the DialOption interface.
|
||||||
type funcDialOption struct {
|
type funcDialOption struct {
|
||||||
@ -126,6 +139,20 @@ func newJoinDialOption(opts ...DialOption) DialOption {
|
|||||||
return &joinDialOption{opts: opts}
|
return &joinDialOption{opts: opts}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithSharedWriteBuffer allows reusing per-connection transport write buffer.
|
||||||
|
// If this option is set to true every connection will release the buffer after
|
||||||
|
// flushing the data on the wire.
|
||||||
|
//
|
||||||
|
// # Experimental
|
||||||
|
//
|
||||||
|
// Notice: This API is EXPERIMENTAL and may be changed or removed in a
|
||||||
|
// later release.
|
||||||
|
func WithSharedWriteBuffer(val bool) DialOption {
|
||||||
|
return newFuncDialOption(func(o *dialOptions) {
|
||||||
|
o.copts.SharedWriteBuffer = val
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// WithWriteBufferSize determines how much data can be batched before doing a
|
// WithWriteBufferSize determines how much data can be batched before doing a
|
||||||
// write on the wire. The corresponding memory allocation for this buffer will
|
// write on the wire. The corresponding memory allocation for this buffer will
|
||||||
// be twice the size to keep syscalls low. The default value for this buffer is
|
// be twice the size to keep syscalls low. The default value for this buffer is
|
||||||
@ -284,6 +311,9 @@ func withBackoff(bs internalbackoff.Strategy) DialOption {
|
|||||||
// WithBlock returns a DialOption which makes callers of Dial block until the
|
// WithBlock returns a DialOption which makes callers of Dial block until the
|
||||||
// underlying connection is up. Without this, Dial returns immediately and
|
// underlying connection is up. Without this, Dial returns immediately and
|
||||||
// connecting the server happens in background.
|
// connecting the server happens in background.
|
||||||
|
//
|
||||||
|
// Use of this feature is not recommended. For more information, please see:
|
||||||
|
// https://github.com/grpc/grpc-go/blob/master/Documentation/anti-patterns.md
|
||||||
func WithBlock() DialOption {
|
func WithBlock() DialOption {
|
||||||
return newFuncDialOption(func(o *dialOptions) {
|
return newFuncDialOption(func(o *dialOptions) {
|
||||||
o.block = true
|
o.block = true
|
||||||
@ -295,6 +325,9 @@ func WithBlock() DialOption {
|
|||||||
// the context.DeadlineExceeded error.
|
// the context.DeadlineExceeded error.
|
||||||
// Implies WithBlock()
|
// Implies WithBlock()
|
||||||
//
|
//
|
||||||
|
// Use of this feature is not recommended. For more information, please see:
|
||||||
|
// https://github.com/grpc/grpc-go/blob/master/Documentation/anti-patterns.md
|
||||||
|
//
|
||||||
// # Experimental
|
// # Experimental
|
||||||
//
|
//
|
||||||
// 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
|
||||||
@ -437,6 +470,9 @@ func withBinaryLogger(bl binarylog.Logger) DialOption {
|
|||||||
// FailOnNonTempDialError only affects the initial dial, and does not do
|
// FailOnNonTempDialError only affects the initial dial, and does not do
|
||||||
// anything useful unless you are also using WithBlock().
|
// anything useful unless you are also using WithBlock().
|
||||||
//
|
//
|
||||||
|
// Use of this feature is not recommended. For more information, please see:
|
||||||
|
// https://github.com/grpc/grpc-go/blob/master/Documentation/anti-patterns.md
|
||||||
|
//
|
||||||
// # Experimental
|
// # Experimental
|
||||||
//
|
//
|
||||||
// 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
|
||||||
@ -607,6 +643,7 @@ func defaultDialOptions() dialOptions {
|
|||||||
ReadBufferSize: defaultReadBufSize,
|
ReadBufferSize: defaultReadBufSize,
|
||||||
UseProxy: true,
|
UseProxy: true,
|
||||||
},
|
},
|
||||||
|
recvBufferPool: nopBufferPool{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -635,3 +672,44 @@ func WithResolvers(rs ...resolver.Builder) DialOption {
|
|||||||
o.resolvers = append(o.resolvers, rs...)
|
o.resolvers = append(o.resolvers, rs...)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithIdleTimeout returns a DialOption that configures an idle timeout for the
|
||||||
|
// channel. If the channel is idle for the configured timeout, i.e there are no
|
||||||
|
// ongoing RPCs and no new RPCs are initiated, the channel will enter idle mode
|
||||||
|
// and as a result the name resolver and load balancer will be shut down. The
|
||||||
|
// channel will exit idle mode when the Connect() method is called or when an
|
||||||
|
// RPC is initiated.
|
||||||
|
//
|
||||||
|
// By default this feature is disabled, which can also be explicitly configured
|
||||||
|
// by passing zero to this function.
|
||||||
|
//
|
||||||
|
// # Experimental
|
||||||
|
//
|
||||||
|
// Notice: This API is EXPERIMENTAL and may be changed or removed in a
|
||||||
|
// later release.
|
||||||
|
func WithIdleTimeout(d time.Duration) DialOption {
|
||||||
|
return newFuncDialOption(func(o *dialOptions) {
|
||||||
|
o.idleTimeout = d
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithRecvBufferPool returns a DialOption that configures the ClientConn
|
||||||
|
// to use the provided shared buffer pool for parsing incoming messages. Depending
|
||||||
|
// on the application's workload, this could result in reduced memory allocation.
|
||||||
|
//
|
||||||
|
// If you are unsure about how to implement a memory pool but want to utilize one,
|
||||||
|
// begin with grpc.NewSharedBufferPool.
|
||||||
|
//
|
||||||
|
// Note: The shared buffer pool feature will not be active if any of the following
|
||||||
|
// options are used: WithStatsHandler, EnableTracing, or binary logging. In such
|
||||||
|
// cases, the shared buffer pool will be ignored.
|
||||||
|
//
|
||||||
|
// # Experimental
|
||||||
|
//
|
||||||
|
// Notice: This API is EXPERIMENTAL and may be changed or removed in a
|
||||||
|
// later release.
|
||||||
|
func WithRecvBufferPool(bufferPool SharedBufferPool) DialOption {
|
||||||
|
return newFuncDialOption(func(o *dialOptions) {
|
||||||
|
o.recvBufferPool = bufferPool
|
||||||
|
})
|
||||||
|
}
|
||||||
|
4
vendor/google.golang.org/grpc/encoding/encoding.go
generated
vendored
4
vendor/google.golang.org/grpc/encoding/encoding.go
generated
vendored
@ -90,9 +90,9 @@ func GetCompressor(name string) Compressor {
|
|||||||
// methods can be called from concurrent goroutines.
|
// methods can be called from concurrent goroutines.
|
||||||
type Codec interface {
|
type Codec interface {
|
||||||
// Marshal returns the wire format of v.
|
// Marshal returns the wire format of v.
|
||||||
Marshal(v interface{}) ([]byte, error)
|
Marshal(v any) ([]byte, error)
|
||||||
// Unmarshal parses the wire format into v.
|
// Unmarshal parses the wire format into v.
|
||||||
Unmarshal(data []byte, v interface{}) error
|
Unmarshal(data []byte, v any) error
|
||||||
// Name returns the name of the Codec implementation. The returned string
|
// Name returns the name of the Codec implementation. The returned string
|
||||||
// will be used as part of content type in transmission. The result must be
|
// will be used as part of content type in transmission. The result must be
|
||||||
// static; the result cannot change between calls.
|
// static; the result cannot change between calls.
|
||||||
|
4
vendor/google.golang.org/grpc/encoding/gzip/gzip.go
generated
vendored
4
vendor/google.golang.org/grpc/encoding/gzip/gzip.go
generated
vendored
@ -40,7 +40,7 @@ const Name = "gzip"
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
c := &compressor{}
|
c := &compressor{}
|
||||||
c.poolCompressor.New = func() interface{} {
|
c.poolCompressor.New = func() any {
|
||||||
return &writer{Writer: gzip.NewWriter(io.Discard), pool: &c.poolCompressor}
|
return &writer{Writer: gzip.NewWriter(io.Discard), pool: &c.poolCompressor}
|
||||||
}
|
}
|
||||||
encoding.RegisterCompressor(c)
|
encoding.RegisterCompressor(c)
|
||||||
@ -61,7 +61,7 @@ func SetLevel(level int) error {
|
|||||||
return fmt.Errorf("grpc: invalid gzip compression level: %d", level)
|
return fmt.Errorf("grpc: invalid gzip compression level: %d", level)
|
||||||
}
|
}
|
||||||
c := encoding.GetCompressor(Name).(*compressor)
|
c := encoding.GetCompressor(Name).(*compressor)
|
||||||
c.poolCompressor.New = func() interface{} {
|
c.poolCompressor.New = func() any {
|
||||||
w, err := gzip.NewWriterLevel(io.Discard, level)
|
w, err := gzip.NewWriterLevel(io.Discard, level)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
4
vendor/google.golang.org/grpc/encoding/proto/proto.go
generated
vendored
4
vendor/google.golang.org/grpc/encoding/proto/proto.go
generated
vendored
@ -37,7 +37,7 @@ func init() {
|
|||||||
// codec is a Codec implementation with protobuf. It is the default codec for gRPC.
|
// codec is a Codec implementation with protobuf. It is the default codec for gRPC.
|
||||||
type codec struct{}
|
type codec struct{}
|
||||||
|
|
||||||
func (codec) Marshal(v interface{}) ([]byte, error) {
|
func (codec) Marshal(v any) ([]byte, error) {
|
||||||
vv, ok := v.(proto.Message)
|
vv, ok := v.(proto.Message)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("failed to marshal, message is %T, want proto.Message", v)
|
return nil, fmt.Errorf("failed to marshal, message is %T, want proto.Message", v)
|
||||||
@ -45,7 +45,7 @@ func (codec) Marshal(v interface{}) ([]byte, error) {
|
|||||||
return proto.Marshal(vv)
|
return proto.Marshal(vv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (codec) Unmarshal(data []byte, v interface{}) error {
|
func (codec) Unmarshal(data []byte, v any) error {
|
||||||
vv, ok := v.(proto.Message)
|
vv, ok := v.(proto.Message)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("failed to unmarshal, message is %T, want proto.Message", v)
|
return fmt.Errorf("failed to unmarshal, message is %T, want proto.Message", v)
|
||||||
|
40
vendor/google.golang.org/grpc/grpclog/component.go
generated
vendored
40
vendor/google.golang.org/grpc/grpclog/component.go
generated
vendored
@ -31,71 +31,71 @@ type componentData struct {
|
|||||||
|
|
||||||
var cache = map[string]*componentData{}
|
var cache = map[string]*componentData{}
|
||||||
|
|
||||||
func (c *componentData) InfoDepth(depth int, args ...interface{}) {
|
func (c *componentData) InfoDepth(depth int, args ...any) {
|
||||||
args = append([]interface{}{"[" + string(c.name) + "]"}, args...)
|
args = append([]any{"[" + string(c.name) + "]"}, args...)
|
||||||
grpclog.InfoDepth(depth+1, args...)
|
grpclog.InfoDepth(depth+1, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *componentData) WarningDepth(depth int, args ...interface{}) {
|
func (c *componentData) WarningDepth(depth int, args ...any) {
|
||||||
args = append([]interface{}{"[" + string(c.name) + "]"}, args...)
|
args = append([]any{"[" + string(c.name) + "]"}, args...)
|
||||||
grpclog.WarningDepth(depth+1, args...)
|
grpclog.WarningDepth(depth+1, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *componentData) ErrorDepth(depth int, args ...interface{}) {
|
func (c *componentData) ErrorDepth(depth int, args ...any) {
|
||||||
args = append([]interface{}{"[" + string(c.name) + "]"}, args...)
|
args = append([]any{"[" + string(c.name) + "]"}, args...)
|
||||||
grpclog.ErrorDepth(depth+1, args...)
|
grpclog.ErrorDepth(depth+1, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *componentData) FatalDepth(depth int, args ...interface{}) {
|
func (c *componentData) FatalDepth(depth int, args ...any) {
|
||||||
args = append([]interface{}{"[" + string(c.name) + "]"}, args...)
|
args = append([]any{"[" + string(c.name) + "]"}, args...)
|
||||||
grpclog.FatalDepth(depth+1, args...)
|
grpclog.FatalDepth(depth+1, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *componentData) Info(args ...interface{}) {
|
func (c *componentData) Info(args ...any) {
|
||||||
c.InfoDepth(1, args...)
|
c.InfoDepth(1, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *componentData) Warning(args ...interface{}) {
|
func (c *componentData) Warning(args ...any) {
|
||||||
c.WarningDepth(1, args...)
|
c.WarningDepth(1, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *componentData) Error(args ...interface{}) {
|
func (c *componentData) Error(args ...any) {
|
||||||
c.ErrorDepth(1, args...)
|
c.ErrorDepth(1, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *componentData) Fatal(args ...interface{}) {
|
func (c *componentData) Fatal(args ...any) {
|
||||||
c.FatalDepth(1, args...)
|
c.FatalDepth(1, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *componentData) Infof(format string, args ...interface{}) {
|
func (c *componentData) Infof(format string, args ...any) {
|
||||||
c.InfoDepth(1, fmt.Sprintf(format, args...))
|
c.InfoDepth(1, fmt.Sprintf(format, args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *componentData) Warningf(format string, args ...interface{}) {
|
func (c *componentData) Warningf(format string, args ...any) {
|
||||||
c.WarningDepth(1, fmt.Sprintf(format, args...))
|
c.WarningDepth(1, fmt.Sprintf(format, args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *componentData) Errorf(format string, args ...interface{}) {
|
func (c *componentData) Errorf(format string, args ...any) {
|
||||||
c.ErrorDepth(1, fmt.Sprintf(format, args...))
|
c.ErrorDepth(1, fmt.Sprintf(format, args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *componentData) Fatalf(format string, args ...interface{}) {
|
func (c *componentData) Fatalf(format string, args ...any) {
|
||||||
c.FatalDepth(1, fmt.Sprintf(format, args...))
|
c.FatalDepth(1, fmt.Sprintf(format, args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *componentData) Infoln(args ...interface{}) {
|
func (c *componentData) Infoln(args ...any) {
|
||||||
c.InfoDepth(1, args...)
|
c.InfoDepth(1, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *componentData) Warningln(args ...interface{}) {
|
func (c *componentData) Warningln(args ...any) {
|
||||||
c.WarningDepth(1, args...)
|
c.WarningDepth(1, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *componentData) Errorln(args ...interface{}) {
|
func (c *componentData) Errorln(args ...any) {
|
||||||
c.ErrorDepth(1, args...)
|
c.ErrorDepth(1, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *componentData) Fatalln(args ...interface{}) {
|
func (c *componentData) Fatalln(args ...any) {
|
||||||
c.FatalDepth(1, args...)
|
c.FatalDepth(1, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
30
vendor/google.golang.org/grpc/grpclog/grpclog.go
generated
vendored
30
vendor/google.golang.org/grpc/grpclog/grpclog.go
generated
vendored
@ -42,53 +42,53 @@ func V(l int) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Info logs to the INFO log.
|
// Info logs to the INFO log.
|
||||||
func Info(args ...interface{}) {
|
func Info(args ...any) {
|
||||||
grpclog.Logger.Info(args...)
|
grpclog.Logger.Info(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Infof logs to the INFO log. Arguments are handled in the manner of fmt.Printf.
|
// Infof logs to the INFO log. Arguments are handled in the manner of fmt.Printf.
|
||||||
func Infof(format string, args ...interface{}) {
|
func Infof(format string, args ...any) {
|
||||||
grpclog.Logger.Infof(format, args...)
|
grpclog.Logger.Infof(format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Infoln logs to the INFO log. Arguments are handled in the manner of fmt.Println.
|
// Infoln logs to the INFO log. Arguments are handled in the manner of fmt.Println.
|
||||||
func Infoln(args ...interface{}) {
|
func Infoln(args ...any) {
|
||||||
grpclog.Logger.Infoln(args...)
|
grpclog.Logger.Infoln(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warning logs to the WARNING log.
|
// Warning logs to the WARNING log.
|
||||||
func Warning(args ...interface{}) {
|
func Warning(args ...any) {
|
||||||
grpclog.Logger.Warning(args...)
|
grpclog.Logger.Warning(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warningf logs to the WARNING log. Arguments are handled in the manner of fmt.Printf.
|
// Warningf logs to the WARNING log. Arguments are handled in the manner of fmt.Printf.
|
||||||
func Warningf(format string, args ...interface{}) {
|
func Warningf(format string, args ...any) {
|
||||||
grpclog.Logger.Warningf(format, args...)
|
grpclog.Logger.Warningf(format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warningln logs to the WARNING log. Arguments are handled in the manner of fmt.Println.
|
// Warningln logs to the WARNING log. Arguments are handled in the manner of fmt.Println.
|
||||||
func Warningln(args ...interface{}) {
|
func Warningln(args ...any) {
|
||||||
grpclog.Logger.Warningln(args...)
|
grpclog.Logger.Warningln(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error logs to the ERROR log.
|
// Error logs to the ERROR log.
|
||||||
func Error(args ...interface{}) {
|
func Error(args ...any) {
|
||||||
grpclog.Logger.Error(args...)
|
grpclog.Logger.Error(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Errorf logs to the ERROR log. Arguments are handled in the manner of fmt.Printf.
|
// Errorf logs to the ERROR log. Arguments are handled in the manner of fmt.Printf.
|
||||||
func Errorf(format string, args ...interface{}) {
|
func Errorf(format string, args ...any) {
|
||||||
grpclog.Logger.Errorf(format, args...)
|
grpclog.Logger.Errorf(format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Errorln logs to the ERROR log. Arguments are handled in the manner of fmt.Println.
|
// Errorln logs to the ERROR log. Arguments are handled in the manner of fmt.Println.
|
||||||
func Errorln(args ...interface{}) {
|
func Errorln(args ...any) {
|
||||||
grpclog.Logger.Errorln(args...)
|
grpclog.Logger.Errorln(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fatal logs to the FATAL log. Arguments are handled in the manner of fmt.Print.
|
// Fatal logs to the FATAL log. Arguments are handled in the manner of fmt.Print.
|
||||||
// It calls os.Exit() with exit code 1.
|
// It calls os.Exit() with exit code 1.
|
||||||
func Fatal(args ...interface{}) {
|
func Fatal(args ...any) {
|
||||||
grpclog.Logger.Fatal(args...)
|
grpclog.Logger.Fatal(args...)
|
||||||
// Make sure fatal logs will exit.
|
// Make sure fatal logs will exit.
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@ -96,7 +96,7 @@ func Fatal(args ...interface{}) {
|
|||||||
|
|
||||||
// Fatalf logs to the FATAL log. Arguments are handled in the manner of fmt.Printf.
|
// Fatalf logs to the FATAL log. Arguments are handled in the manner of fmt.Printf.
|
||||||
// It calls os.Exit() with exit code 1.
|
// It calls os.Exit() with exit code 1.
|
||||||
func Fatalf(format string, args ...interface{}) {
|
func Fatalf(format string, args ...any) {
|
||||||
grpclog.Logger.Fatalf(format, args...)
|
grpclog.Logger.Fatalf(format, args...)
|
||||||
// Make sure fatal logs will exit.
|
// Make sure fatal logs will exit.
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@ -104,7 +104,7 @@ func Fatalf(format string, args ...interface{}) {
|
|||||||
|
|
||||||
// Fatalln logs to the FATAL log. Arguments are handled in the manner of fmt.Println.
|
// Fatalln logs to the FATAL log. Arguments are handled in the manner of fmt.Println.
|
||||||
// It calle os.Exit()) with exit code 1.
|
// It calle os.Exit()) with exit code 1.
|
||||||
func Fatalln(args ...interface{}) {
|
func Fatalln(args ...any) {
|
||||||
grpclog.Logger.Fatalln(args...)
|
grpclog.Logger.Fatalln(args...)
|
||||||
// Make sure fatal logs will exit.
|
// Make sure fatal logs will exit.
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@ -113,20 +113,20 @@ func Fatalln(args ...interface{}) {
|
|||||||
// Print prints to the logger. Arguments are handled in the manner of fmt.Print.
|
// Print prints to the logger. Arguments are handled in the manner of fmt.Print.
|
||||||
//
|
//
|
||||||
// Deprecated: use Info.
|
// Deprecated: use Info.
|
||||||
func Print(args ...interface{}) {
|
func Print(args ...any) {
|
||||||
grpclog.Logger.Info(args...)
|
grpclog.Logger.Info(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Printf prints to the logger. Arguments are handled in the manner of fmt.Printf.
|
// Printf prints to the logger. Arguments are handled in the manner of fmt.Printf.
|
||||||
//
|
//
|
||||||
// Deprecated: use Infof.
|
// Deprecated: use Infof.
|
||||||
func Printf(format string, args ...interface{}) {
|
func Printf(format string, args ...any) {
|
||||||
grpclog.Logger.Infof(format, args...)
|
grpclog.Logger.Infof(format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Println prints to the logger. Arguments are handled in the manner of fmt.Println.
|
// Println prints to the logger. Arguments are handled in the manner of fmt.Println.
|
||||||
//
|
//
|
||||||
// Deprecated: use Infoln.
|
// Deprecated: use Infoln.
|
||||||
func Println(args ...interface{}) {
|
func Println(args ...any) {
|
||||||
grpclog.Logger.Infoln(args...)
|
grpclog.Logger.Infoln(args...)
|
||||||
}
|
}
|
||||||
|
30
vendor/google.golang.org/grpc/grpclog/logger.go
generated
vendored
30
vendor/google.golang.org/grpc/grpclog/logger.go
generated
vendored
@ -24,12 +24,12 @@ import "google.golang.org/grpc/internal/grpclog"
|
|||||||
//
|
//
|
||||||
// Deprecated: use LoggerV2.
|
// Deprecated: use LoggerV2.
|
||||||
type Logger interface {
|
type Logger interface {
|
||||||
Fatal(args ...interface{})
|
Fatal(args ...any)
|
||||||
Fatalf(format string, args ...interface{})
|
Fatalf(format string, args ...any)
|
||||||
Fatalln(args ...interface{})
|
Fatalln(args ...any)
|
||||||
Print(args ...interface{})
|
Print(args ...any)
|
||||||
Printf(format string, args ...interface{})
|
Printf(format string, args ...any)
|
||||||
Println(args ...interface{})
|
Println(args ...any)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetLogger sets the logger that is used in grpc. Call only from
|
// SetLogger sets the logger that is used in grpc. Call only from
|
||||||
@ -45,39 +45,39 @@ type loggerWrapper struct {
|
|||||||
Logger
|
Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *loggerWrapper) Info(args ...interface{}) {
|
func (g *loggerWrapper) Info(args ...any) {
|
||||||
g.Logger.Print(args...)
|
g.Logger.Print(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *loggerWrapper) Infoln(args ...interface{}) {
|
func (g *loggerWrapper) Infoln(args ...any) {
|
||||||
g.Logger.Println(args...)
|
g.Logger.Println(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *loggerWrapper) Infof(format string, args ...interface{}) {
|
func (g *loggerWrapper) Infof(format string, args ...any) {
|
||||||
g.Logger.Printf(format, args...)
|
g.Logger.Printf(format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *loggerWrapper) Warning(args ...interface{}) {
|
func (g *loggerWrapper) Warning(args ...any) {
|
||||||
g.Logger.Print(args...)
|
g.Logger.Print(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *loggerWrapper) Warningln(args ...interface{}) {
|
func (g *loggerWrapper) Warningln(args ...any) {
|
||||||
g.Logger.Println(args...)
|
g.Logger.Println(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *loggerWrapper) Warningf(format string, args ...interface{}) {
|
func (g *loggerWrapper) Warningf(format string, args ...any) {
|
||||||
g.Logger.Printf(format, args...)
|
g.Logger.Printf(format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *loggerWrapper) Error(args ...interface{}) {
|
func (g *loggerWrapper) Error(args ...any) {
|
||||||
g.Logger.Print(args...)
|
g.Logger.Print(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *loggerWrapper) Errorln(args ...interface{}) {
|
func (g *loggerWrapper) Errorln(args ...any) {
|
||||||
g.Logger.Println(args...)
|
g.Logger.Println(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *loggerWrapper) Errorf(format string, args ...interface{}) {
|
func (g *loggerWrapper) Errorf(format string, args ...any) {
|
||||||
g.Logger.Printf(format, args...)
|
g.Logger.Printf(format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
56
vendor/google.golang.org/grpc/grpclog/loggerv2.go
generated
vendored
56
vendor/google.golang.org/grpc/grpclog/loggerv2.go
generated
vendored
@ -33,35 +33,35 @@ import (
|
|||||||
// LoggerV2 does underlying logging work for grpclog.
|
// LoggerV2 does underlying logging work for grpclog.
|
||||||
type LoggerV2 interface {
|
type LoggerV2 interface {
|
||||||
// Info logs to INFO log. Arguments are handled in the manner of fmt.Print.
|
// Info logs to INFO log. Arguments are handled in the manner of fmt.Print.
|
||||||
Info(args ...interface{})
|
Info(args ...any)
|
||||||
// Infoln logs to INFO log. Arguments are handled in the manner of fmt.Println.
|
// Infoln logs to INFO log. Arguments are handled in the manner of fmt.Println.
|
||||||
Infoln(args ...interface{})
|
Infoln(args ...any)
|
||||||
// Infof logs to INFO log. Arguments are handled in the manner of fmt.Printf.
|
// Infof logs to INFO log. Arguments are handled in the manner of fmt.Printf.
|
||||||
Infof(format string, args ...interface{})
|
Infof(format string, args ...any)
|
||||||
// Warning logs to WARNING log. Arguments are handled in the manner of fmt.Print.
|
// Warning logs to WARNING log. Arguments are handled in the manner of fmt.Print.
|
||||||
Warning(args ...interface{})
|
Warning(args ...any)
|
||||||
// Warningln logs to WARNING log. Arguments are handled in the manner of fmt.Println.
|
// Warningln logs to WARNING log. Arguments are handled in the manner of fmt.Println.
|
||||||
Warningln(args ...interface{})
|
Warningln(args ...any)
|
||||||
// Warningf logs to WARNING log. Arguments are handled in the manner of fmt.Printf.
|
// Warningf logs to WARNING log. Arguments are handled in the manner of fmt.Printf.
|
||||||
Warningf(format string, args ...interface{})
|
Warningf(format string, args ...any)
|
||||||
// Error logs to ERROR log. Arguments are handled in the manner of fmt.Print.
|
// Error logs to ERROR log. Arguments are handled in the manner of fmt.Print.
|
||||||
Error(args ...interface{})
|
Error(args ...any)
|
||||||
// Errorln logs to ERROR log. Arguments are handled in the manner of fmt.Println.
|
// Errorln logs to ERROR log. Arguments are handled in the manner of fmt.Println.
|
||||||
Errorln(args ...interface{})
|
Errorln(args ...any)
|
||||||
// Errorf logs to ERROR log. Arguments are handled in the manner of fmt.Printf.
|
// Errorf logs to ERROR log. Arguments are handled in the manner of fmt.Printf.
|
||||||
Errorf(format string, args ...interface{})
|
Errorf(format string, args ...any)
|
||||||
// Fatal logs to ERROR log. Arguments are handled in the manner of fmt.Print.
|
// Fatal logs to ERROR log. Arguments are handled in the manner of fmt.Print.
|
||||||
// gRPC ensures that all Fatal logs will exit with os.Exit(1).
|
// gRPC ensures that all Fatal logs will exit with os.Exit(1).
|
||||||
// Implementations may also call os.Exit() with a non-zero exit code.
|
// Implementations may also call os.Exit() with a non-zero exit code.
|
||||||
Fatal(args ...interface{})
|
Fatal(args ...any)
|
||||||
// Fatalln logs to ERROR log. Arguments are handled in the manner of fmt.Println.
|
// Fatalln logs to ERROR log. Arguments are handled in the manner of fmt.Println.
|
||||||
// gRPC ensures that all Fatal logs will exit with os.Exit(1).
|
// gRPC ensures that all Fatal logs will exit with os.Exit(1).
|
||||||
// Implementations may also call os.Exit() with a non-zero exit code.
|
// Implementations may also call os.Exit() with a non-zero exit code.
|
||||||
Fatalln(args ...interface{})
|
Fatalln(args ...any)
|
||||||
// Fatalf logs to ERROR log. Arguments are handled in the manner of fmt.Printf.
|
// Fatalf logs to ERROR log. Arguments are handled in the manner of fmt.Printf.
|
||||||
// gRPC ensures that all Fatal logs will exit with os.Exit(1).
|
// gRPC ensures that all Fatal logs will exit with os.Exit(1).
|
||||||
// Implementations may also call os.Exit() with a non-zero exit code.
|
// Implementations may also call os.Exit() with a non-zero exit code.
|
||||||
Fatalf(format string, args ...interface{})
|
Fatalf(format string, args ...any)
|
||||||
// V reports whether verbosity level l is at least the requested verbose level.
|
// V reports whether verbosity level l is at least the requested verbose level.
|
||||||
V(l int) bool
|
V(l int) bool
|
||||||
}
|
}
|
||||||
@ -182,53 +182,53 @@ func (g *loggerT) output(severity int, s string) {
|
|||||||
g.m[severity].Output(2, string(b))
|
g.m[severity].Output(2, string(b))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *loggerT) Info(args ...interface{}) {
|
func (g *loggerT) Info(args ...any) {
|
||||||
g.output(infoLog, fmt.Sprint(args...))
|
g.output(infoLog, fmt.Sprint(args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *loggerT) Infoln(args ...interface{}) {
|
func (g *loggerT) Infoln(args ...any) {
|
||||||
g.output(infoLog, fmt.Sprintln(args...))
|
g.output(infoLog, fmt.Sprintln(args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *loggerT) Infof(format string, args ...interface{}) {
|
func (g *loggerT) Infof(format string, args ...any) {
|
||||||
g.output(infoLog, fmt.Sprintf(format, args...))
|
g.output(infoLog, fmt.Sprintf(format, args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *loggerT) Warning(args ...interface{}) {
|
func (g *loggerT) Warning(args ...any) {
|
||||||
g.output(warningLog, fmt.Sprint(args...))
|
g.output(warningLog, fmt.Sprint(args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *loggerT) Warningln(args ...interface{}) {
|
func (g *loggerT) Warningln(args ...any) {
|
||||||
g.output(warningLog, fmt.Sprintln(args...))
|
g.output(warningLog, fmt.Sprintln(args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *loggerT) Warningf(format string, args ...interface{}) {
|
func (g *loggerT) Warningf(format string, args ...any) {
|
||||||
g.output(warningLog, fmt.Sprintf(format, args...))
|
g.output(warningLog, fmt.Sprintf(format, args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *loggerT) Error(args ...interface{}) {
|
func (g *loggerT) Error(args ...any) {
|
||||||
g.output(errorLog, fmt.Sprint(args...))
|
g.output(errorLog, fmt.Sprint(args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *loggerT) Errorln(args ...interface{}) {
|
func (g *loggerT) Errorln(args ...any) {
|
||||||
g.output(errorLog, fmt.Sprintln(args...))
|
g.output(errorLog, fmt.Sprintln(args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *loggerT) Errorf(format string, args ...interface{}) {
|
func (g *loggerT) Errorf(format string, args ...any) {
|
||||||
g.output(errorLog, fmt.Sprintf(format, args...))
|
g.output(errorLog, fmt.Sprintf(format, args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *loggerT) Fatal(args ...interface{}) {
|
func (g *loggerT) Fatal(args ...any) {
|
||||||
g.output(fatalLog, fmt.Sprint(args...))
|
g.output(fatalLog, fmt.Sprint(args...))
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *loggerT) Fatalln(args ...interface{}) {
|
func (g *loggerT) Fatalln(args ...any) {
|
||||||
g.output(fatalLog, fmt.Sprintln(args...))
|
g.output(fatalLog, fmt.Sprintln(args...))
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *loggerT) Fatalf(format string, args ...interface{}) {
|
func (g *loggerT) Fatalf(format string, args ...any) {
|
||||||
g.output(fatalLog, fmt.Sprintf(format, args...))
|
g.output(fatalLog, fmt.Sprintf(format, args...))
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
@ -248,11 +248,11 @@ func (g *loggerT) V(l int) bool {
|
|||||||
type DepthLoggerV2 interface {
|
type DepthLoggerV2 interface {
|
||||||
LoggerV2
|
LoggerV2
|
||||||
// InfoDepth logs to INFO log at the specified depth. Arguments are handled in the manner of fmt.Println.
|
// InfoDepth logs to INFO log at the specified depth. Arguments are handled in the manner of fmt.Println.
|
||||||
InfoDepth(depth int, args ...interface{})
|
InfoDepth(depth int, args ...any)
|
||||||
// WarningDepth logs to WARNING log at the specified depth. Arguments are handled in the manner of fmt.Println.
|
// WarningDepth logs to WARNING log at the specified depth. Arguments are handled in the manner of fmt.Println.
|
||||||
WarningDepth(depth int, args ...interface{})
|
WarningDepth(depth int, args ...any)
|
||||||
// ErrorDepth logs to ERROR log at the specified depth. Arguments are handled in the manner of fmt.Println.
|
// ErrorDepth logs to ERROR log at the specified depth. Arguments are handled in the manner of fmt.Println.
|
||||||
ErrorDepth(depth int, args ...interface{})
|
ErrorDepth(depth int, args ...any)
|
||||||
// FatalDepth logs to FATAL log at the specified depth. Arguments are handled in the manner of fmt.Println.
|
// FatalDepth logs to FATAL log at the specified depth. Arguments are handled in the manner of fmt.Println.
|
||||||
FatalDepth(depth int, args ...interface{})
|
FatalDepth(depth int, args ...any)
|
||||||
}
|
}
|
||||||
|
2
vendor/google.golang.org/grpc/health/client.go
generated
vendored
2
vendor/google.golang.org/grpc/health/client.go
generated
vendored
@ -56,7 +56,7 @@ const healthCheckMethod = "/grpc.health.v1.Health/Watch"
|
|||||||
|
|
||||||
// This function implements the protocol defined at:
|
// This function implements the protocol defined at:
|
||||||
// https://github.com/grpc/grpc/blob/master/doc/health-checking.md
|
// https://github.com/grpc/grpc/blob/master/doc/health-checking.md
|
||||||
func clientHealthCheck(ctx context.Context, newStream func(string) (interface{}, error), setConnectivityState func(connectivity.State, error), service string) error {
|
func clientHealthCheck(ctx context.Context, newStream func(string) (any, error), setConnectivityState func(connectivity.State, error), service string) error {
|
||||||
tryCnt := 0
|
tryCnt := 0
|
||||||
|
|
||||||
retryConnection:
|
retryConnection:
|
||||||
|
4
vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go
generated
vendored
4
vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go
generated
vendored
@ -17,8 +17,8 @@
|
|||||||
|
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.28.1
|
// protoc-gen-go v1.31.0
|
||||||
// protoc v3.14.0
|
// protoc v4.22.0
|
||||||
// source: grpc/health/v1/health.proto
|
// source: grpc/health/v1/health.proto
|
||||||
|
|
||||||
package grpc_health_v1
|
package grpc_health_v1
|
||||||
|
15
vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go
generated
vendored
15
vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go
generated
vendored
@ -17,8 +17,8 @@
|
|||||||
|
|
||||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// - protoc-gen-go-grpc v1.2.0
|
// - protoc-gen-go-grpc v1.3.0
|
||||||
// - protoc v3.14.0
|
// - protoc v4.22.0
|
||||||
// source: grpc/health/v1/health.proto
|
// source: grpc/health/v1/health.proto
|
||||||
|
|
||||||
package grpc_health_v1
|
package grpc_health_v1
|
||||||
@ -35,6 +35,11 @@ import (
|
|||||||
// Requires gRPC-Go v1.32.0 or later.
|
// Requires gRPC-Go v1.32.0 or later.
|
||||||
const _ = grpc.SupportPackageIsVersion7
|
const _ = grpc.SupportPackageIsVersion7
|
||||||
|
|
||||||
|
const (
|
||||||
|
Health_Check_FullMethodName = "/grpc.health.v1.Health/Check"
|
||||||
|
Health_Watch_FullMethodName = "/grpc.health.v1.Health/Watch"
|
||||||
|
)
|
||||||
|
|
||||||
// HealthClient is the client API for Health service.
|
// HealthClient is the client API for Health service.
|
||||||
//
|
//
|
||||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||||
@ -70,7 +75,7 @@ func NewHealthClient(cc grpc.ClientConnInterface) HealthClient {
|
|||||||
|
|
||||||
func (c *healthClient) Check(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error) {
|
func (c *healthClient) Check(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error) {
|
||||||
out := new(HealthCheckResponse)
|
out := new(HealthCheckResponse)
|
||||||
err := c.cc.Invoke(ctx, "/grpc.health.v1.Health/Check", in, out, opts...)
|
err := c.cc.Invoke(ctx, Health_Check_FullMethodName, in, out, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -78,7 +83,7 @@ func (c *healthClient) Check(ctx context.Context, in *HealthCheckRequest, opts .
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *healthClient) Watch(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (Health_WatchClient, error) {
|
func (c *healthClient) Watch(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (Health_WatchClient, error) {
|
||||||
stream, err := c.cc.NewStream(ctx, &Health_ServiceDesc.Streams[0], "/grpc.health.v1.Health/Watch", opts...)
|
stream, err := c.cc.NewStream(ctx, &Health_ServiceDesc.Streams[0], Health_Watch_FullMethodName, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -166,7 +171,7 @@ func _Health_Check_Handler(srv interface{}, ctx context.Context, dec func(interf
|
|||||||
}
|
}
|
||||||
info := &grpc.UnaryServerInfo{
|
info := &grpc.UnaryServerInfo{
|
||||||
Server: srv,
|
Server: srv,
|
||||||
FullMethod: "/grpc.health.v1.Health/Check",
|
FullMethod: Health_Check_FullMethodName,
|
||||||
}
|
}
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
return srv.(HealthServer).Check(ctx, req.(*HealthCheckRequest))
|
return srv.(HealthServer).Check(ctx, req.(*HealthCheckRequest))
|
||||||
|
12
vendor/google.golang.org/grpc/interceptor.go
generated
vendored
12
vendor/google.golang.org/grpc/interceptor.go
generated
vendored
@ -23,7 +23,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// UnaryInvoker is called by UnaryClientInterceptor to complete RPCs.
|
// UnaryInvoker is called by UnaryClientInterceptor to complete RPCs.
|
||||||
type UnaryInvoker func(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, opts ...CallOption) error
|
type UnaryInvoker func(ctx context.Context, method string, req, reply any, cc *ClientConn, opts ...CallOption) error
|
||||||
|
|
||||||
// UnaryClientInterceptor intercepts the execution of a unary RPC on the client.
|
// UnaryClientInterceptor intercepts the execution of a unary RPC on the client.
|
||||||
// Unary interceptors can be specified as a DialOption, using
|
// Unary interceptors can be specified as a DialOption, using
|
||||||
@ -40,7 +40,7 @@ type UnaryInvoker func(ctx context.Context, method string, req, reply interface{
|
|||||||
// defaults from the ClientConn as well as per-call options.
|
// defaults from the ClientConn as well as per-call options.
|
||||||
//
|
//
|
||||||
// The returned error must be compatible with the status package.
|
// The returned error must be compatible with the status package.
|
||||||
type UnaryClientInterceptor func(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, invoker UnaryInvoker, opts ...CallOption) error
|
type UnaryClientInterceptor func(ctx context.Context, method string, req, reply any, cc *ClientConn, invoker UnaryInvoker, opts ...CallOption) error
|
||||||
|
|
||||||
// Streamer is called by StreamClientInterceptor to create a ClientStream.
|
// Streamer is called by StreamClientInterceptor to create a ClientStream.
|
||||||
type Streamer func(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (ClientStream, error)
|
type Streamer func(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (ClientStream, error)
|
||||||
@ -66,7 +66,7 @@ type StreamClientInterceptor func(ctx context.Context, desc *StreamDesc, cc *Cli
|
|||||||
// server side. All per-rpc information may be mutated by the interceptor.
|
// server side. All per-rpc information may be mutated by the interceptor.
|
||||||
type UnaryServerInfo struct {
|
type UnaryServerInfo struct {
|
||||||
// Server is the service implementation the user provides. This is read-only.
|
// Server is the service implementation the user provides. This is read-only.
|
||||||
Server interface{}
|
Server any
|
||||||
// FullMethod is the full RPC method string, i.e., /package.service/method.
|
// FullMethod is the full RPC method string, i.e., /package.service/method.
|
||||||
FullMethod string
|
FullMethod string
|
||||||
}
|
}
|
||||||
@ -78,13 +78,13 @@ type UnaryServerInfo struct {
|
|||||||
// status package, or be one of the context errors. Otherwise, gRPC will use
|
// status package, or be one of the context errors. Otherwise, gRPC will use
|
||||||
// codes.Unknown as the status code and err.Error() as the status message of the
|
// codes.Unknown as the status code and err.Error() as the status message of the
|
||||||
// RPC.
|
// RPC.
|
||||||
type UnaryHandler func(ctx context.Context, req interface{}) (interface{}, error)
|
type UnaryHandler func(ctx context.Context, req any) (any, error)
|
||||||
|
|
||||||
// UnaryServerInterceptor provides a hook to intercept the execution of a unary RPC on the server. info
|
// UnaryServerInterceptor provides a hook to intercept the execution of a unary RPC on the server. info
|
||||||
// contains all the information of this RPC the interceptor can operate on. And handler is the wrapper
|
// contains all the information of this RPC the interceptor can operate on. And handler is the wrapper
|
||||||
// of the service method implementation. It is the responsibility of the interceptor to invoke handler
|
// of the service method implementation. It is the responsibility of the interceptor to invoke handler
|
||||||
// to complete the RPC.
|
// to complete the RPC.
|
||||||
type UnaryServerInterceptor func(ctx context.Context, req interface{}, info *UnaryServerInfo, handler UnaryHandler) (resp interface{}, err error)
|
type UnaryServerInterceptor func(ctx context.Context, req any, info *UnaryServerInfo, handler UnaryHandler) (resp any, err error)
|
||||||
|
|
||||||
// StreamServerInfo consists of various information about a streaming RPC on
|
// StreamServerInfo consists of various information about a streaming RPC on
|
||||||
// server side. All per-rpc information may be mutated by the interceptor.
|
// server side. All per-rpc information may be mutated by the interceptor.
|
||||||
@ -101,4 +101,4 @@ type StreamServerInfo struct {
|
|||||||
// info contains all the information of this RPC the interceptor can operate on. And handler is the
|
// info contains all the information of this RPC the interceptor can operate on. And handler is the
|
||||||
// service method implementation. It is the responsibility of the interceptor to invoke handler to
|
// service method implementation. It is the responsibility of the interceptor to invoke handler to
|
||||||
// complete the RPC.
|
// complete the RPC.
|
||||||
type StreamServerInterceptor func(srv interface{}, ss ServerStream, info *StreamServerInfo, handler StreamHandler) error
|
type StreamServerInterceptor func(srv any, ss ServerStream, info *StreamServerInfo, handler StreamHandler) error
|
||||||
|
57
vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go
generated
vendored
57
vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go
generated
vendored
@ -200,8 +200,8 @@ func (gsb *Balancer) ExitIdle() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateSubConnState forwards the update to the appropriate child.
|
// updateSubConnState forwards the update to the appropriate child.
|
||||||
func (gsb *Balancer) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) {
|
func (gsb *Balancer) updateSubConnState(sc balancer.SubConn, state balancer.SubConnState, cb func(balancer.SubConnState)) {
|
||||||
gsb.currentMu.Lock()
|
gsb.currentMu.Lock()
|
||||||
defer gsb.currentMu.Unlock()
|
defer gsb.currentMu.Unlock()
|
||||||
gsb.mu.Lock()
|
gsb.mu.Lock()
|
||||||
@ -214,14 +214,27 @@ func (gsb *Balancer) UpdateSubConnState(sc balancer.SubConn, state balancer.SubC
|
|||||||
} else if gsb.balancerPending != nil && gsb.balancerPending.subconns[sc] {
|
} else if gsb.balancerPending != nil && gsb.balancerPending.subconns[sc] {
|
||||||
balToUpdate = gsb.balancerPending
|
balToUpdate = gsb.balancerPending
|
||||||
}
|
}
|
||||||
gsb.mu.Unlock()
|
|
||||||
if balToUpdate == nil {
|
if balToUpdate == nil {
|
||||||
// SubConn belonged to a stale lb policy that has not yet fully closed,
|
// SubConn belonged to a stale lb policy that has not yet fully closed,
|
||||||
// or the balancer was already closed.
|
// or the balancer was already closed.
|
||||||
|
gsb.mu.Unlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if state.ConnectivityState == connectivity.Shutdown {
|
||||||
|
delete(balToUpdate.subconns, sc)
|
||||||
|
}
|
||||||
|
gsb.mu.Unlock()
|
||||||
|
if cb != nil {
|
||||||
|
cb(state)
|
||||||
|
} else {
|
||||||
balToUpdate.UpdateSubConnState(sc, state)
|
balToUpdate.UpdateSubConnState(sc, state)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateSubConnState forwards the update to the appropriate child.
|
||||||
|
func (gsb *Balancer) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) {
|
||||||
|
gsb.updateSubConnState(sc, state, nil)
|
||||||
|
}
|
||||||
|
|
||||||
// Close closes any active child balancers.
|
// Close closes any active child balancers.
|
||||||
func (gsb *Balancer) Close() {
|
func (gsb *Balancer) Close() {
|
||||||
@ -242,7 +255,7 @@ func (gsb *Balancer) Close() {
|
|||||||
//
|
//
|
||||||
// It implements the balancer.ClientConn interface and is passed down in that
|
// 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
|
// 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
|
// the wrapped balancer and calls from the latter to create/update/shutdown
|
||||||
// SubConns update this set before being forwarded to the parent ClientConn.
|
// SubConns update this set before being forwarded to the parent ClientConn.
|
||||||
// State updates from the wrapped balancer can result in invocation of the
|
// State updates from the wrapped balancer can result in invocation of the
|
||||||
// graceful switch logic.
|
// graceful switch logic.
|
||||||
@ -254,21 +267,10 @@ type balancerWrapper struct {
|
|||||||
subconns map[balancer.SubConn]bool // subconns created by this balancer
|
subconns map[balancer.SubConn]bool // subconns created by this balancer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bw *balancerWrapper) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) {
|
// Close closes the underlying LB policy and shuts down the subconns it
|
||||||
if state.ConnectivityState == connectivity.Shutdown {
|
// created. bw must not be referenced via balancerCurrent or balancerPending in
|
||||||
bw.gsb.mu.Lock()
|
// gsb when called. gsb.mu must not be held. Does not panic with a nil
|
||||||
delete(bw.subconns, sc)
|
// receiver.
|
||||||
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() {
|
func (bw *balancerWrapper) Close() {
|
||||||
// before Close is called.
|
// before Close is called.
|
||||||
if bw == nil {
|
if bw == nil {
|
||||||
@ -281,7 +283,7 @@ func (bw *balancerWrapper) Close() {
|
|||||||
bw.Balancer.Close()
|
bw.Balancer.Close()
|
||||||
bw.gsb.mu.Lock()
|
bw.gsb.mu.Lock()
|
||||||
for sc := range bw.subconns {
|
for sc := range bw.subconns {
|
||||||
bw.gsb.cc.RemoveSubConn(sc)
|
sc.Shutdown()
|
||||||
}
|
}
|
||||||
bw.gsb.mu.Unlock()
|
bw.gsb.mu.Unlock()
|
||||||
}
|
}
|
||||||
@ -335,13 +337,16 @@ func (bw *balancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer.Ne
|
|||||||
}
|
}
|
||||||
bw.gsb.mu.Unlock()
|
bw.gsb.mu.Unlock()
|
||||||
|
|
||||||
|
var sc balancer.SubConn
|
||||||
|
oldListener := opts.StateListener
|
||||||
|
opts.StateListener = func(state balancer.SubConnState) { bw.gsb.updateSubConnState(sc, state, oldListener) }
|
||||||
sc, err := bw.gsb.cc.NewSubConn(addrs, opts)
|
sc, err := bw.gsb.cc.NewSubConn(addrs, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
bw.gsb.mu.Lock()
|
bw.gsb.mu.Lock()
|
||||||
if !bw.gsb.balancerCurrentOrPending(bw) { // balancer was closed during this call
|
if !bw.gsb.balancerCurrentOrPending(bw) { // balancer was closed during this call
|
||||||
bw.gsb.cc.RemoveSubConn(sc)
|
sc.Shutdown()
|
||||||
bw.gsb.mu.Unlock()
|
bw.gsb.mu.Unlock()
|
||||||
return nil, fmt.Errorf("%T at address %p that called NewSubConn is deleted", bw, bw)
|
return nil, fmt.Errorf("%T at address %p that called NewSubConn is deleted", bw, bw)
|
||||||
}
|
}
|
||||||
@ -360,13 +365,9 @@ func (bw *balancerWrapper) ResolveNow(opts resolver.ResolveNowOptions) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (bw *balancerWrapper) RemoveSubConn(sc balancer.SubConn) {
|
func (bw *balancerWrapper) RemoveSubConn(sc balancer.SubConn) {
|
||||||
bw.gsb.mu.Lock()
|
// Note: existing third party balancers may call this, so it must remain
|
||||||
if !bw.gsb.balancerCurrentOrPending(bw) {
|
// until RemoveSubConn is fully removed.
|
||||||
bw.gsb.mu.Unlock()
|
sc.Shutdown()
|
||||||
return
|
|
||||||
}
|
|
||||||
bw.gsb.mu.Unlock()
|
|
||||||
bw.gsb.cc.RemoveSubConn(sc)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bw *balancerWrapper) UpdateAddresses(sc balancer.SubConn, addrs []resolver.Address) {
|
func (bw *balancerWrapper) UpdateAddresses(sc balancer.SubConn, addrs []resolver.Address) {
|
||||||
|
4
vendor/google.golang.org/grpc/internal/balancerload/load.go
generated
vendored
4
vendor/google.golang.org/grpc/internal/balancerload/load.go
generated
vendored
@ -25,7 +25,7 @@ import (
|
|||||||
// Parser converts loads from metadata into a concrete type.
|
// Parser converts loads from metadata into a concrete type.
|
||||||
type Parser interface {
|
type Parser interface {
|
||||||
// Parse parses loads from metadata.
|
// Parse parses loads from metadata.
|
||||||
Parse(md metadata.MD) interface{}
|
Parse(md metadata.MD) any
|
||||||
}
|
}
|
||||||
|
|
||||||
var parser Parser
|
var parser Parser
|
||||||
@ -38,7 +38,7 @@ func SetParser(lr Parser) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse calls parser.Read().
|
// Parse calls parser.Read().
|
||||||
func Parse(md metadata.MD) interface{} {
|
func Parse(md metadata.MD) any {
|
||||||
if parser == nil {
|
if parser == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
11
vendor/google.golang.org/grpc/internal/binarylog/binarylog.go
generated
vendored
11
vendor/google.golang.org/grpc/internal/binarylog/binarylog.go
generated
vendored
@ -28,8 +28,13 @@ import (
|
|||||||
"google.golang.org/grpc/internal/grpcutil"
|
"google.golang.org/grpc/internal/grpcutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Logger is the global binary logger. It can be used to get binary logger for
|
var grpclogLogger = grpclog.Component("binarylog")
|
||||||
// each method.
|
|
||||||
|
// Logger specifies MethodLoggers for method names with a Log call that
|
||||||
|
// takes a context.
|
||||||
|
//
|
||||||
|
// This is used in the 1.0 release of gcp/observability, and thus must not be
|
||||||
|
// deleted or changed.
|
||||||
type Logger interface {
|
type Logger interface {
|
||||||
GetMethodLogger(methodName string) MethodLogger
|
GetMethodLogger(methodName string) MethodLogger
|
||||||
}
|
}
|
||||||
@ -40,8 +45,6 @@ type Logger interface {
|
|||||||
// It is used to get a MethodLogger for each individual method.
|
// It is used to get a MethodLogger for each individual method.
|
||||||
var binLogger Logger
|
var binLogger Logger
|
||||||
|
|
||||||
var grpclogLogger = grpclog.Component("binarylog")
|
|
||||||
|
|
||||||
// SetLogger sets the binary logger.
|
// SetLogger sets the binary logger.
|
||||||
//
|
//
|
||||||
// Only call this at init time.
|
// Only call this at init time.
|
||||||
|
18
vendor/google.golang.org/grpc/internal/binarylog/method_logger.go
generated
vendored
18
vendor/google.golang.org/grpc/internal/binarylog/method_logger.go
generated
vendored
@ -19,6 +19,7 @@
|
|||||||
package binarylog
|
package binarylog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
@ -48,8 +49,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.
|
||||||
|
//
|
||||||
|
// This is used in the 1.0 release of gcp/observability, and thus must not be
|
||||||
|
// deleted or changed.
|
||||||
type MethodLogger interface {
|
type MethodLogger interface {
|
||||||
Log(LogEntryConfig)
|
Log(context.Context, LogEntryConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TruncatingMethodLogger is a method logger that truncates headers and messages
|
// TruncatingMethodLogger is a method logger that truncates headers and messages
|
||||||
@ -64,6 +68,9 @@ type TruncatingMethodLogger struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewTruncatingMethodLogger returns a new truncating method logger.
|
// NewTruncatingMethodLogger returns a new truncating method logger.
|
||||||
|
//
|
||||||
|
// This is used in the 1.0 release of gcp/observability, and thus must not be
|
||||||
|
// deleted or changed.
|
||||||
func NewTruncatingMethodLogger(h, m uint64) *TruncatingMethodLogger {
|
func NewTruncatingMethodLogger(h, m uint64) *TruncatingMethodLogger {
|
||||||
return &TruncatingMethodLogger{
|
return &TruncatingMethodLogger{
|
||||||
headerMaxLen: h,
|
headerMaxLen: h,
|
||||||
@ -98,7 +105,7 @@ func (ml *TruncatingMethodLogger) Build(c LogEntryConfig) *binlogpb.GrpcLogEntry
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Log creates a proto binary log entry, and logs it to the sink.
|
// Log creates a proto binary log entry, and logs it to the sink.
|
||||||
func (ml *TruncatingMethodLogger) Log(c LogEntryConfig) {
|
func (ml *TruncatingMethodLogger) Log(ctx context.Context, c LogEntryConfig) {
|
||||||
ml.sink.Write(ml.Build(c))
|
ml.sink.Write(ml.Build(c))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,6 +151,9 @@ func (ml *TruncatingMethodLogger) truncateMessage(msgPb *binlogpb.Message) (trun
|
|||||||
}
|
}
|
||||||
|
|
||||||
// LogEntryConfig represents the configuration for binary log entry.
|
// LogEntryConfig represents the configuration for binary log entry.
|
||||||
|
//
|
||||||
|
// This is used in the 1.0 release of gcp/observability, and thus must not be
|
||||||
|
// deleted or changed.
|
||||||
type LogEntryConfig interface {
|
type LogEntryConfig interface {
|
||||||
toProto() *binlogpb.GrpcLogEntry
|
toProto() *binlogpb.GrpcLogEntry
|
||||||
}
|
}
|
||||||
@ -220,7 +230,7 @@ type ClientMessage struct {
|
|||||||
OnClientSide bool
|
OnClientSide bool
|
||||||
// Message can be a proto.Message or []byte. Other messages formats are not
|
// Message can be a proto.Message or []byte. Other messages formats are not
|
||||||
// supported.
|
// supported.
|
||||||
Message interface{}
|
Message any
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ClientMessage) toProto() *binlogpb.GrpcLogEntry {
|
func (c *ClientMessage) toProto() *binlogpb.GrpcLogEntry {
|
||||||
@ -260,7 +270,7 @@ type ServerMessage struct {
|
|||||||
OnClientSide bool
|
OnClientSide bool
|
||||||
// Message can be a proto.Message or []byte. Other messages formats are not
|
// Message can be a proto.Message or []byte. Other messages formats are not
|
||||||
// supported.
|
// supported.
|
||||||
Message interface{}
|
Message any
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ServerMessage) toProto() *binlogpb.GrpcLogEntry {
|
func (c *ServerMessage) toProto() *binlogpb.GrpcLogEntry {
|
||||||
|
44
vendor/google.golang.org/grpc/internal/buffer/unbounded.go
generated
vendored
44
vendor/google.golang.org/grpc/internal/buffer/unbounded.go
generated
vendored
@ -28,35 +28,38 @@ import "sync"
|
|||||||
// the underlying mutex used for synchronization.
|
// the underlying mutex used for synchronization.
|
||||||
//
|
//
|
||||||
// Unbounded supports values of any type to be stored in it by using a channel
|
// Unbounded supports values of any type to be stored in it by using a channel
|
||||||
// of `interface{}`. This means that a call to Put() incurs an extra memory
|
// of `any`. This means that a call to Put() incurs an extra memory allocation,
|
||||||
// allocation, and also that users need a type assertion while reading. For
|
// and also that users need a type assertion while reading. For performance
|
||||||
// performance critical code paths, using Unbounded is strongly discouraged and
|
// critical code paths, using Unbounded is strongly discouraged and defining a
|
||||||
// defining a new type specific implementation of this buffer is preferred. See
|
// new type specific implementation of this buffer is preferred. See
|
||||||
// internal/transport/transport.go for an example of this.
|
// internal/transport/transport.go for an example of this.
|
||||||
type Unbounded struct {
|
type Unbounded struct {
|
||||||
c chan interface{}
|
c chan any
|
||||||
|
closed bool
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
backlog []interface{}
|
backlog []any
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewUnbounded returns a new instance of Unbounded.
|
// NewUnbounded returns a new instance of Unbounded.
|
||||||
func NewUnbounded() *Unbounded {
|
func NewUnbounded() *Unbounded {
|
||||||
return &Unbounded{c: make(chan interface{}, 1)}
|
return &Unbounded{c: make(chan any, 1)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put adds t to the unbounded buffer.
|
// Put adds t to the unbounded buffer.
|
||||||
func (b *Unbounded) Put(t interface{}) {
|
func (b *Unbounded) Put(t any) {
|
||||||
b.mu.Lock()
|
b.mu.Lock()
|
||||||
|
defer b.mu.Unlock()
|
||||||
|
if b.closed {
|
||||||
|
return
|
||||||
|
}
|
||||||
if len(b.backlog) == 0 {
|
if len(b.backlog) == 0 {
|
||||||
select {
|
select {
|
||||||
case b.c <- t:
|
case b.c <- t:
|
||||||
b.mu.Unlock()
|
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b.backlog = append(b.backlog, t)
|
b.backlog = append(b.backlog, t)
|
||||||
b.mu.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load sends the earliest buffered data, if any, onto the read channel
|
// Load sends the earliest buffered data, if any, onto the read channel
|
||||||
@ -64,6 +67,10 @@ func (b *Unbounded) Put(t interface{}) {
|
|||||||
// value from the read channel.
|
// value from the read channel.
|
||||||
func (b *Unbounded) Load() {
|
func (b *Unbounded) Load() {
|
||||||
b.mu.Lock()
|
b.mu.Lock()
|
||||||
|
defer b.mu.Unlock()
|
||||||
|
if b.closed {
|
||||||
|
return
|
||||||
|
}
|
||||||
if len(b.backlog) > 0 {
|
if len(b.backlog) > 0 {
|
||||||
select {
|
select {
|
||||||
case b.c <- b.backlog[0]:
|
case b.c <- b.backlog[0]:
|
||||||
@ -72,7 +79,6 @@ func (b *Unbounded) Load() {
|
|||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b.mu.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get returns a read channel on which values added to the buffer, via Put(),
|
// Get returns a read channel on which values added to the buffer, via Put(),
|
||||||
@ -80,6 +86,20 @@ func (b *Unbounded) Load() {
|
|||||||
//
|
//
|
||||||
// Upon reading a value from this channel, users are expected to call Load() to
|
// Upon reading a value from this channel, users are expected to call Load() to
|
||||||
// send the next buffered value onto the channel if there is any.
|
// send the next buffered value onto the channel if there is any.
|
||||||
func (b *Unbounded) Get() <-chan interface{} {
|
//
|
||||||
|
// If the unbounded buffer is closed, the read channel returned by this method
|
||||||
|
// is closed.
|
||||||
|
func (b *Unbounded) Get() <-chan any {
|
||||||
return b.c
|
return b.c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close closes the unbounded buffer.
|
||||||
|
func (b *Unbounded) Close() {
|
||||||
|
b.mu.Lock()
|
||||||
|
defer b.mu.Unlock()
|
||||||
|
if b.closed {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
b.closed = true
|
||||||
|
close(b.c)
|
||||||
|
}
|
||||||
|
67
vendor/google.golang.org/grpc/internal/channelz/funcs.go
generated
vendored
67
vendor/google.golang.org/grpc/internal/channelz/funcs.go
generated
vendored
@ -24,9 +24,7 @@
|
|||||||
package channelz
|
package channelz
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"sort"
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
@ -40,8 +38,11 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// IDGen is the global channelz entity ID generator. It should not be used
|
||||||
|
// outside this package except by tests.
|
||||||
|
IDGen IDGenerator
|
||||||
|
|
||||||
db dbWrapper
|
db dbWrapper
|
||||||
idGen idGenerator
|
|
||||||
// EntryPerPage defines the number of channelz entries to be shown on a web page.
|
// EntryPerPage defines the number of channelz entries to be shown on a web page.
|
||||||
EntryPerPage = int64(50)
|
EntryPerPage = int64(50)
|
||||||
curState int32
|
curState int32
|
||||||
@ -52,14 +53,14 @@ var (
|
|||||||
func TurnOn() {
|
func TurnOn() {
|
||||||
if !IsOn() {
|
if !IsOn() {
|
||||||
db.set(newChannelMap())
|
db.set(newChannelMap())
|
||||||
idGen.reset()
|
IDGen.Reset()
|
||||||
atomic.StoreInt32(&curState, 1)
|
atomic.StoreInt32(&curState, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsOn returns whether channelz data collection is on.
|
// IsOn returns whether channelz data collection is on.
|
||||||
func IsOn() bool {
|
func IsOn() bool {
|
||||||
return atomic.CompareAndSwapInt32(&curState, 1, 1)
|
return atomic.LoadInt32(&curState) == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetMaxTraceEntry sets maximum number of trace entry per entity (i.e. channel/subchannel).
|
// SetMaxTraceEntry sets maximum number of trace entry per entity (i.e. channel/subchannel).
|
||||||
@ -97,43 +98,6 @@ func (d *dbWrapper) get() *channelMap {
|
|||||||
return d.DB
|
return d.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewChannelzStorageForTesting initializes channelz data storage and id
|
|
||||||
// generator for testing purposes.
|
|
||||||
//
|
|
||||||
// Returns a cleanup function to be invoked by the test, which waits for up to
|
|
||||||
// 10s for all channelz state to be reset by the grpc goroutines when those
|
|
||||||
// entities get closed. This cleanup function helps with ensuring that tests
|
|
||||||
// don't mess up each other.
|
|
||||||
func NewChannelzStorageForTesting() (cleanup func() error) {
|
|
||||||
db.set(newChannelMap())
|
|
||||||
idGen.reset()
|
|
||||||
|
|
||||||
return func() error {
|
|
||||||
cm := db.get()
|
|
||||||
if cm == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
ticker := time.NewTicker(10 * time.Millisecond)
|
|
||||||
defer ticker.Stop()
|
|
||||||
for {
|
|
||||||
cm.mu.RLock()
|
|
||||||
topLevelChannels, servers, channels, subChannels, listenSockets, normalSockets := len(cm.topLevelChannels), len(cm.servers), len(cm.channels), len(cm.subChannels), len(cm.listenSockets), len(cm.normalSockets)
|
|
||||||
cm.mu.RUnlock()
|
|
||||||
|
|
||||||
if err := ctx.Err(); err != nil {
|
|
||||||
return fmt.Errorf("after 10s the channelz map has not been cleaned up yet, topchannels: %d, servers: %d, channels: %d, subchannels: %d, listen sockets: %d, normal sockets: %d", topLevelChannels, servers, channels, subChannels, listenSockets, normalSockets)
|
|
||||||
}
|
|
||||||
if topLevelChannels == 0 && servers == 0 && channels == 0 && subChannels == 0 && listenSockets == 0 && normalSockets == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
<-ticker.C
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetTopChannels returns a slice of top channel's ChannelMetric, along with a
|
// GetTopChannels returns a slice of top channel's ChannelMetric, along with a
|
||||||
// boolean indicating whether there's more top channels to be queried for.
|
// boolean indicating whether there's more top channels to be queried for.
|
||||||
//
|
//
|
||||||
@ -193,7 +157,7 @@ func GetServer(id int64) *ServerMetric {
|
|||||||
//
|
//
|
||||||
// If channelz is not turned ON, the channelz database is not mutated.
|
// If channelz is not turned ON, the channelz database is not mutated.
|
||||||
func RegisterChannel(c Channel, pid *Identifier, ref string) *Identifier {
|
func RegisterChannel(c Channel, pid *Identifier, ref string) *Identifier {
|
||||||
id := idGen.genID()
|
id := IDGen.genID()
|
||||||
var parent int64
|
var parent int64
|
||||||
isTopChannel := true
|
isTopChannel := true
|
||||||
if pid != nil {
|
if pid != nil {
|
||||||
@ -229,7 +193,7 @@ func RegisterSubChannel(c Channel, pid *Identifier, ref string) (*Identifier, er
|
|||||||
if pid == nil {
|
if pid == nil {
|
||||||
return nil, errors.New("a SubChannel's parent id cannot be nil")
|
return nil, errors.New("a SubChannel's parent id cannot be nil")
|
||||||
}
|
}
|
||||||
id := idGen.genID()
|
id := IDGen.genID()
|
||||||
if !IsOn() {
|
if !IsOn() {
|
||||||
return newIdentifer(RefSubChannel, id, pid), nil
|
return newIdentifer(RefSubChannel, id, pid), nil
|
||||||
}
|
}
|
||||||
@ -251,7 +215,7 @@ func RegisterSubChannel(c Channel, pid *Identifier, ref string) (*Identifier, er
|
|||||||
//
|
//
|
||||||
// If channelz is not turned ON, the channelz database is not mutated.
|
// If channelz is not turned ON, the channelz database is not mutated.
|
||||||
func RegisterServer(s Server, ref string) *Identifier {
|
func RegisterServer(s Server, ref string) *Identifier {
|
||||||
id := idGen.genID()
|
id := IDGen.genID()
|
||||||
if !IsOn() {
|
if !IsOn() {
|
||||||
return newIdentifer(RefServer, id, nil)
|
return newIdentifer(RefServer, id, nil)
|
||||||
}
|
}
|
||||||
@ -277,7 +241,7 @@ func RegisterListenSocket(s Socket, pid *Identifier, ref string) (*Identifier, e
|
|||||||
if pid == nil {
|
if pid == nil {
|
||||||
return nil, errors.New("a ListenSocket's parent id cannot be 0")
|
return nil, errors.New("a ListenSocket's parent id cannot be 0")
|
||||||
}
|
}
|
||||||
id := idGen.genID()
|
id := IDGen.genID()
|
||||||
if !IsOn() {
|
if !IsOn() {
|
||||||
return newIdentifer(RefListenSocket, id, pid), nil
|
return newIdentifer(RefListenSocket, id, pid), nil
|
||||||
}
|
}
|
||||||
@ -297,7 +261,7 @@ func RegisterNormalSocket(s Socket, pid *Identifier, ref string) (*Identifier, e
|
|||||||
if pid == nil {
|
if pid == nil {
|
||||||
return nil, errors.New("a NormalSocket's parent id cannot be 0")
|
return nil, errors.New("a NormalSocket's parent id cannot be 0")
|
||||||
}
|
}
|
||||||
id := idGen.genID()
|
id := IDGen.genID()
|
||||||
if !IsOn() {
|
if !IsOn() {
|
||||||
return newIdentifer(RefNormalSocket, id, pid), nil
|
return newIdentifer(RefNormalSocket, id, pid), nil
|
||||||
}
|
}
|
||||||
@ -776,14 +740,17 @@ func (c *channelMap) GetServer(id int64) *ServerMetric {
|
|||||||
return sm
|
return sm
|
||||||
}
|
}
|
||||||
|
|
||||||
type idGenerator struct {
|
// IDGenerator is an incrementing atomic that tracks IDs for channelz entities.
|
||||||
|
type IDGenerator struct {
|
||||||
id int64
|
id int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *idGenerator) reset() {
|
// Reset resets the generated ID back to zero. Should only be used at
|
||||||
|
// initialization or by tests sensitive to the ID number.
|
||||||
|
func (i *IDGenerator) Reset() {
|
||||||
atomic.StoreInt64(&i.id, 0)
|
atomic.StoreInt64(&i.id, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *idGenerator) genID() int64 {
|
func (i *IDGenerator) genID() int64 {
|
||||||
return atomic.AddInt64(&i.id, 1)
|
return atomic.AddInt64(&i.id, 1)
|
||||||
}
|
}
|
||||||
|
12
vendor/google.golang.org/grpc/internal/channelz/logging.go
generated
vendored
12
vendor/google.golang.org/grpc/internal/channelz/logging.go
generated
vendored
@ -31,7 +31,7 @@ func withParens(id *Identifier) 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 *Identifier, args ...interface{}) {
|
func Info(l grpclog.DepthLoggerV2, id *Identifier, args ...any) {
|
||||||
AddTraceEvent(l, id, 1, &TraceEventDesc{
|
AddTraceEvent(l, id, 1, &TraceEventDesc{
|
||||||
Desc: fmt.Sprint(args...),
|
Desc: fmt.Sprint(args...),
|
||||||
Severity: CtInfo,
|
Severity: CtInfo,
|
||||||
@ -39,7 +39,7 @@ func Info(l grpclog.DepthLoggerV2, id *Identifier, args ...interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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 *Identifier, format string, args ...interface{}) {
|
func Infof(l grpclog.DepthLoggerV2, id *Identifier, format string, args ...any) {
|
||||||
AddTraceEvent(l, id, 1, &TraceEventDesc{
|
AddTraceEvent(l, id, 1, &TraceEventDesc{
|
||||||
Desc: fmt.Sprintf(format, args...),
|
Desc: fmt.Sprintf(format, args...),
|
||||||
Severity: CtInfo,
|
Severity: CtInfo,
|
||||||
@ -47,7 +47,7 @@ func Infof(l grpclog.DepthLoggerV2, id *Identifier, format string, args ...inter
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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 *Identifier, args ...interface{}) {
|
func Warning(l grpclog.DepthLoggerV2, id *Identifier, args ...any) {
|
||||||
AddTraceEvent(l, id, 1, &TraceEventDesc{
|
AddTraceEvent(l, id, 1, &TraceEventDesc{
|
||||||
Desc: fmt.Sprint(args...),
|
Desc: fmt.Sprint(args...),
|
||||||
Severity: CtWarning,
|
Severity: CtWarning,
|
||||||
@ -55,7 +55,7 @@ func Warning(l grpclog.DepthLoggerV2, id *Identifier, args ...interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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 *Identifier, format string, args ...interface{}) {
|
func Warningf(l grpclog.DepthLoggerV2, id *Identifier, format string, args ...any) {
|
||||||
AddTraceEvent(l, id, 1, &TraceEventDesc{
|
AddTraceEvent(l, id, 1, &TraceEventDesc{
|
||||||
Desc: fmt.Sprintf(format, args...),
|
Desc: fmt.Sprintf(format, args...),
|
||||||
Severity: CtWarning,
|
Severity: CtWarning,
|
||||||
@ -63,7 +63,7 @@ func Warningf(l grpclog.DepthLoggerV2, id *Identifier, format string, args ...in
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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 *Identifier, args ...interface{}) {
|
func Error(l grpclog.DepthLoggerV2, id *Identifier, args ...any) {
|
||||||
AddTraceEvent(l, id, 1, &TraceEventDesc{
|
AddTraceEvent(l, id, 1, &TraceEventDesc{
|
||||||
Desc: fmt.Sprint(args...),
|
Desc: fmt.Sprint(args...),
|
||||||
Severity: CtError,
|
Severity: CtError,
|
||||||
@ -71,7 +71,7 @@ func Error(l grpclog.DepthLoggerV2, id *Identifier, args ...interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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 *Identifier, format string, args ...interface{}) {
|
func Errorf(l grpclog.DepthLoggerV2, id *Identifier, format string, args ...any) {
|
||||||
AddTraceEvent(l, id, 1, &TraceEventDesc{
|
AddTraceEvent(l, id, 1, &TraceEventDesc{
|
||||||
Desc: fmt.Sprintf(format, args...),
|
Desc: fmt.Sprintf(format, args...),
|
||||||
Severity: CtError,
|
Severity: CtError,
|
||||||
|
5
vendor/google.golang.org/grpc/internal/channelz/types.go
generated
vendored
5
vendor/google.golang.org/grpc/internal/channelz/types.go
generated
vendored
@ -628,6 +628,7 @@ type tracedChannel interface {
|
|||||||
|
|
||||||
type channelTrace struct {
|
type channelTrace struct {
|
||||||
cm *channelMap
|
cm *channelMap
|
||||||
|
clearCalled bool
|
||||||
createdTime time.Time
|
createdTime time.Time
|
||||||
eventCount int64
|
eventCount int64
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
@ -656,6 +657,10 @@ func (c *channelTrace) append(e *TraceEvent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *channelTrace) clear() {
|
func (c *channelTrace) clear() {
|
||||||
|
if c.clearCalled {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.clearCalled = true
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
for _, e := range c.events {
|
for _, e := range c.events {
|
||||||
if e.RefID != 0 {
|
if e.RefID != 0 {
|
||||||
|
2
vendor/google.golang.org/grpc/internal/channelz/util_linux.go
generated
vendored
2
vendor/google.golang.org/grpc/internal/channelz/util_linux.go
generated
vendored
@ -23,7 +23,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// GetSocketOption gets the socket option info of the conn.
|
// GetSocketOption gets the socket option info of the conn.
|
||||||
func GetSocketOption(socket interface{}) *SocketOptionData {
|
func GetSocketOption(socket any) *SocketOptionData {
|
||||||
c, ok := socket.(syscall.Conn)
|
c, ok := socket.(syscall.Conn)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
|
2
vendor/google.golang.org/grpc/internal/channelz/util_nonlinux.go
generated
vendored
2
vendor/google.golang.org/grpc/internal/channelz/util_nonlinux.go
generated
vendored
@ -22,6 +22,6 @@
|
|||||||
package channelz
|
package channelz
|
||||||
|
|
||||||
// GetSocketOption gets the socket option info of the conn.
|
// GetSocketOption gets the socket option info of the conn.
|
||||||
func GetSocketOption(c interface{}) *SocketOptionData {
|
func GetSocketOption(c any) *SocketOptionData {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
8
vendor/google.golang.org/grpc/internal/credentials/credentials.go
generated
vendored
8
vendor/google.golang.org/grpc/internal/credentials/credentials.go
generated
vendored
@ -25,12 +25,12 @@ import (
|
|||||||
type requestInfoKey struct{}
|
type requestInfoKey struct{}
|
||||||
|
|
||||||
// NewRequestInfoContext creates a context with ri.
|
// NewRequestInfoContext creates a context with ri.
|
||||||
func NewRequestInfoContext(ctx context.Context, ri interface{}) context.Context {
|
func NewRequestInfoContext(ctx context.Context, ri any) context.Context {
|
||||||
return context.WithValue(ctx, requestInfoKey{}, ri)
|
return context.WithValue(ctx, requestInfoKey{}, ri)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RequestInfoFromContext extracts the RequestInfo from ctx.
|
// RequestInfoFromContext extracts the RequestInfo from ctx.
|
||||||
func RequestInfoFromContext(ctx context.Context) interface{} {
|
func RequestInfoFromContext(ctx context.Context) any {
|
||||||
return ctx.Value(requestInfoKey{})
|
return ctx.Value(requestInfoKey{})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,11 +39,11 @@ func RequestInfoFromContext(ctx context.Context) interface{} {
|
|||||||
type clientHandshakeInfoKey struct{}
|
type clientHandshakeInfoKey struct{}
|
||||||
|
|
||||||
// ClientHandshakeInfoFromContext extracts the ClientHandshakeInfo from ctx.
|
// ClientHandshakeInfoFromContext extracts the ClientHandshakeInfo from ctx.
|
||||||
func ClientHandshakeInfoFromContext(ctx context.Context) interface{} {
|
func ClientHandshakeInfoFromContext(ctx context.Context) any {
|
||||||
return ctx.Value(clientHandshakeInfoKey{})
|
return ctx.Value(clientHandshakeInfoKey{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewClientHandshakeInfoContext creates a context with chi.
|
// NewClientHandshakeInfoContext creates a context with chi.
|
||||||
func NewClientHandshakeInfoContext(ctx context.Context, chi interface{}) context.Context {
|
func NewClientHandshakeInfoContext(ctx context.Context, chi any) context.Context {
|
||||||
return context.WithValue(ctx, clientHandshakeInfoKey{}, chi)
|
return context.WithValue(ctx, clientHandshakeInfoKey{}, chi)
|
||||||
}
|
}
|
||||||
|
10
vendor/google.golang.org/grpc/internal/envconfig/envconfig.go
generated
vendored
10
vendor/google.golang.org/grpc/internal/envconfig/envconfig.go
generated
vendored
@ -36,6 +36,16 @@ var (
|
|||||||
// "GRPC_RING_HASH_CAP". This does not override the default bounds
|
// "GRPC_RING_HASH_CAP". This does not override the default bounds
|
||||||
// checking which NACKs configs specifying ring sizes > 8*1024*1024 (~8M).
|
// checking which NACKs configs specifying ring sizes > 8*1024*1024 (~8M).
|
||||||
RingHashCap = uint64FromEnv("GRPC_RING_HASH_CAP", 4096, 1, 8*1024*1024)
|
RingHashCap = uint64FromEnv("GRPC_RING_HASH_CAP", 4096, 1, 8*1024*1024)
|
||||||
|
// PickFirstLBConfig is set if we should support configuration of the
|
||||||
|
// pick_first LB policy.
|
||||||
|
PickFirstLBConfig = boolFromEnv("GRPC_EXPERIMENTAL_PICKFIRST_LB_CONFIG", true)
|
||||||
|
// LeastRequestLB is set if we should support the least_request_experimental
|
||||||
|
// LB policy, which can be enabled by setting the environment variable
|
||||||
|
// "GRPC_EXPERIMENTAL_ENABLE_LEAST_REQUEST" to "true".
|
||||||
|
LeastRequestLB = boolFromEnv("GRPC_EXPERIMENTAL_ENABLE_LEAST_REQUEST", false)
|
||||||
|
// ALTSMaxConcurrentHandshakes is the maximum number of concurrent ALTS
|
||||||
|
// handshakes that can be performed.
|
||||||
|
ALTSMaxConcurrentHandshakes = uint64FromEnv("GRPC_ALTS_MAX_CONCURRENT_HANDSHAKES", 100, 1, 100)
|
||||||
)
|
)
|
||||||
|
|
||||||
func boolFromEnv(envVar string, def bool) bool {
|
func boolFromEnv(envVar string, def bool) bool {
|
||||||
|
6
vendor/google.golang.org/grpc/internal/envconfig/observability.go
generated
vendored
6
vendor/google.golang.org/grpc/internal/envconfig/observability.go
generated
vendored
@ -28,9 +28,15 @@ const (
|
|||||||
var (
|
var (
|
||||||
// ObservabilityConfig is the json configuration for the gcp/observability
|
// ObservabilityConfig is the json configuration for the gcp/observability
|
||||||
// package specified directly in the envObservabilityConfig env var.
|
// package specified directly in the envObservabilityConfig env var.
|
||||||
|
//
|
||||||
|
// This is used in the 1.0 release of gcp/observability, and thus must not be
|
||||||
|
// deleted or changed.
|
||||||
ObservabilityConfig = os.Getenv(envObservabilityConfig)
|
ObservabilityConfig = os.Getenv(envObservabilityConfig)
|
||||||
// ObservabilityConfigFile is the json configuration for the
|
// ObservabilityConfigFile is the json configuration for the
|
||||||
// gcp/observability specified in a file with the location specified in
|
// gcp/observability specified in a file with the location specified in
|
||||||
// envObservabilityConfigFile env var.
|
// envObservabilityConfigFile env var.
|
||||||
|
//
|
||||||
|
// This is used in the 1.0 release of gcp/observability, and thus must not be
|
||||||
|
// deleted or changed.
|
||||||
ObservabilityConfigFile = os.Getenv(envObservabilityConfigFile)
|
ObservabilityConfigFile = os.Getenv(envObservabilityConfigFile)
|
||||||
)
|
)
|
||||||
|
21
vendor/google.golang.org/grpc/internal/envconfig/xds.go
generated
vendored
21
vendor/google.golang.org/grpc/internal/envconfig/xds.go
generated
vendored
@ -61,11 +61,10 @@ var (
|
|||||||
// have a brand new API on the server-side and users explicitly need to use
|
// have a brand new API on the server-side and users explicitly need to use
|
||||||
// the new API to get security integration on the server.
|
// the new API to get security integration on the server.
|
||||||
XDSClientSideSecurity = boolFromEnv("GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT", true)
|
XDSClientSideSecurity = boolFromEnv("GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT", true)
|
||||||
// XDSAggregateAndDNS indicates whether processing of aggregated cluster
|
// XDSAggregateAndDNS indicates whether processing of aggregated cluster and
|
||||||
// and DNS cluster is enabled, which can be enabled by setting the
|
// DNS cluster is enabled, which can be disabled by setting the environment
|
||||||
// environment variable
|
// variable "GRPC_XDS_EXPERIMENTAL_ENABLE_AGGREGATE_AND_LOGICAL_DNS_CLUSTER"
|
||||||
// "GRPC_XDS_EXPERIMENTAL_ENABLE_AGGREGATE_AND_LOGICAL_DNS_CLUSTER" to
|
// to "false".
|
||||||
// "true".
|
|
||||||
XDSAggregateAndDNS = boolFromEnv("GRPC_XDS_EXPERIMENTAL_ENABLE_AGGREGATE_AND_LOGICAL_DNS_CLUSTER", true)
|
XDSAggregateAndDNS = boolFromEnv("GRPC_XDS_EXPERIMENTAL_ENABLE_AGGREGATE_AND_LOGICAL_DNS_CLUSTER", true)
|
||||||
|
|
||||||
// XDSRBAC indicates whether xDS configured RBAC HTTP Filter is enabled,
|
// XDSRBAC indicates whether xDS configured RBAC HTTP Filter is enabled,
|
||||||
@ -79,14 +78,18 @@ var (
|
|||||||
// XDSFederation indicates whether federation support is enabled, which can
|
// XDSFederation indicates whether federation support is enabled, which can
|
||||||
// be enabled by setting the environment variable
|
// be enabled by setting the environment variable
|
||||||
// "GRPC_EXPERIMENTAL_XDS_FEDERATION" to "true".
|
// "GRPC_EXPERIMENTAL_XDS_FEDERATION" to "true".
|
||||||
XDSFederation = boolFromEnv("GRPC_EXPERIMENTAL_XDS_FEDERATION", false)
|
XDSFederation = boolFromEnv("GRPC_EXPERIMENTAL_XDS_FEDERATION", true)
|
||||||
|
|
||||||
// XDSRLS indicates whether processing of Cluster Specifier plugins and
|
// XDSRLS indicates whether processing of Cluster Specifier plugins and
|
||||||
// support for the RLS CLuster Specifier is enabled, which can be enabled by
|
// support for the RLS CLuster Specifier is enabled, which can be disabled by
|
||||||
// setting the environment variable "GRPC_EXPERIMENTAL_XDS_RLS_LB" to
|
// setting the environment variable "GRPC_EXPERIMENTAL_XDS_RLS_LB" to
|
||||||
// "true".
|
// "false".
|
||||||
XDSRLS = boolFromEnv("GRPC_EXPERIMENTAL_XDS_RLS_LB", false)
|
XDSRLS = boolFromEnv("GRPC_EXPERIMENTAL_XDS_RLS_LB", true)
|
||||||
|
|
||||||
// C2PResolverTestOnlyTrafficDirectorURI is the TD URI for testing.
|
// C2PResolverTestOnlyTrafficDirectorURI is the TD URI for testing.
|
||||||
C2PResolverTestOnlyTrafficDirectorURI = os.Getenv("GRPC_TEST_ONLY_GOOGLE_C2P_RESOLVER_TRAFFIC_DIRECTOR_URI")
|
C2PResolverTestOnlyTrafficDirectorURI = os.Getenv("GRPC_TEST_ONLY_GOOGLE_C2P_RESOLVER_TRAFFIC_DIRECTOR_URI")
|
||||||
|
// XDSCustomLBPolicy indicates whether Custom LB Policies are enabled, which
|
||||||
|
// can be disabled by setting the environment variable
|
||||||
|
// "GRPC_EXPERIMENTAL_XDS_CUSTOM_LB_CONFIG" to "false".
|
||||||
|
XDSCustomLBPolicy = boolFromEnv("GRPC_EXPERIMENTAL_XDS_CUSTOM_LB_CONFIG", true)
|
||||||
)
|
)
|
||||||
|
40
vendor/google.golang.org/grpc/internal/grpclog/grpclog.go
generated
vendored
40
vendor/google.golang.org/grpc/internal/grpclog/grpclog.go
generated
vendored
@ -30,7 +30,7 @@ var Logger LoggerV2
|
|||||||
var DepthLogger DepthLoggerV2
|
var DepthLogger DepthLoggerV2
|
||||||
|
|
||||||
// InfoDepth logs to the INFO log at the specified depth.
|
// InfoDepth logs to the INFO log at the specified depth.
|
||||||
func InfoDepth(depth int, args ...interface{}) {
|
func InfoDepth(depth int, args ...any) {
|
||||||
if DepthLogger != nil {
|
if DepthLogger != nil {
|
||||||
DepthLogger.InfoDepth(depth, args...)
|
DepthLogger.InfoDepth(depth, args...)
|
||||||
} else {
|
} else {
|
||||||
@ -39,7 +39,7 @@ func InfoDepth(depth int, args ...interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WarningDepth logs to the WARNING log at the specified depth.
|
// WarningDepth logs to the WARNING log at the specified depth.
|
||||||
func WarningDepth(depth int, args ...interface{}) {
|
func WarningDepth(depth int, args ...any) {
|
||||||
if DepthLogger != nil {
|
if DepthLogger != nil {
|
||||||
DepthLogger.WarningDepth(depth, args...)
|
DepthLogger.WarningDepth(depth, args...)
|
||||||
} else {
|
} else {
|
||||||
@ -48,7 +48,7 @@ func WarningDepth(depth int, args ...interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ErrorDepth logs to the ERROR log at the specified depth.
|
// ErrorDepth logs to the ERROR log at the specified depth.
|
||||||
func ErrorDepth(depth int, args ...interface{}) {
|
func ErrorDepth(depth int, args ...any) {
|
||||||
if DepthLogger != nil {
|
if DepthLogger != nil {
|
||||||
DepthLogger.ErrorDepth(depth, args...)
|
DepthLogger.ErrorDepth(depth, args...)
|
||||||
} else {
|
} else {
|
||||||
@ -57,7 +57,7 @@ func ErrorDepth(depth int, args ...interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FatalDepth logs to the FATAL log at the specified depth.
|
// FatalDepth logs to the FATAL log at the specified depth.
|
||||||
func FatalDepth(depth int, args ...interface{}) {
|
func FatalDepth(depth int, args ...any) {
|
||||||
if DepthLogger != nil {
|
if DepthLogger != nil {
|
||||||
DepthLogger.FatalDepth(depth, args...)
|
DepthLogger.FatalDepth(depth, args...)
|
||||||
} else {
|
} else {
|
||||||
@ -71,35 +71,35 @@ func FatalDepth(depth int, args ...interface{}) {
|
|||||||
// is defined here to avoid a circular dependency.
|
// is defined here to avoid a circular dependency.
|
||||||
type LoggerV2 interface {
|
type LoggerV2 interface {
|
||||||
// Info logs to INFO log. Arguments are handled in the manner of fmt.Print.
|
// Info logs to INFO log. Arguments are handled in the manner of fmt.Print.
|
||||||
Info(args ...interface{})
|
Info(args ...any)
|
||||||
// Infoln logs to INFO log. Arguments are handled in the manner of fmt.Println.
|
// Infoln logs to INFO log. Arguments are handled in the manner of fmt.Println.
|
||||||
Infoln(args ...interface{})
|
Infoln(args ...any)
|
||||||
// Infof logs to INFO log. Arguments are handled in the manner of fmt.Printf.
|
// Infof logs to INFO log. Arguments are handled in the manner of fmt.Printf.
|
||||||
Infof(format string, args ...interface{})
|
Infof(format string, args ...any)
|
||||||
// Warning logs to WARNING log. Arguments are handled in the manner of fmt.Print.
|
// Warning logs to WARNING log. Arguments are handled in the manner of fmt.Print.
|
||||||
Warning(args ...interface{})
|
Warning(args ...any)
|
||||||
// Warningln logs to WARNING log. Arguments are handled in the manner of fmt.Println.
|
// Warningln logs to WARNING log. Arguments are handled in the manner of fmt.Println.
|
||||||
Warningln(args ...interface{})
|
Warningln(args ...any)
|
||||||
// Warningf logs to WARNING log. Arguments are handled in the manner of fmt.Printf.
|
// Warningf logs to WARNING log. Arguments are handled in the manner of fmt.Printf.
|
||||||
Warningf(format string, args ...interface{})
|
Warningf(format string, args ...any)
|
||||||
// Error logs to ERROR log. Arguments are handled in the manner of fmt.Print.
|
// Error logs to ERROR log. Arguments are handled in the manner of fmt.Print.
|
||||||
Error(args ...interface{})
|
Error(args ...any)
|
||||||
// Errorln logs to ERROR log. Arguments are handled in the manner of fmt.Println.
|
// Errorln logs to ERROR log. Arguments are handled in the manner of fmt.Println.
|
||||||
Errorln(args ...interface{})
|
Errorln(args ...any)
|
||||||
// Errorf logs to ERROR log. Arguments are handled in the manner of fmt.Printf.
|
// Errorf logs to ERROR log. Arguments are handled in the manner of fmt.Printf.
|
||||||
Errorf(format string, args ...interface{})
|
Errorf(format string, args ...any)
|
||||||
// Fatal logs to ERROR log. Arguments are handled in the manner of fmt.Print.
|
// Fatal logs to ERROR log. Arguments are handled in the manner of fmt.Print.
|
||||||
// gRPC ensures that all Fatal logs will exit with os.Exit(1).
|
// gRPC ensures that all Fatal logs will exit with os.Exit(1).
|
||||||
// Implementations may also call os.Exit() with a non-zero exit code.
|
// Implementations may also call os.Exit() with a non-zero exit code.
|
||||||
Fatal(args ...interface{})
|
Fatal(args ...any)
|
||||||
// Fatalln logs to ERROR log. Arguments are handled in the manner of fmt.Println.
|
// Fatalln logs to ERROR log. Arguments are handled in the manner of fmt.Println.
|
||||||
// gRPC ensures that all Fatal logs will exit with os.Exit(1).
|
// gRPC ensures that all Fatal logs will exit with os.Exit(1).
|
||||||
// Implementations may also call os.Exit() with a non-zero exit code.
|
// Implementations may also call os.Exit() with a non-zero exit code.
|
||||||
Fatalln(args ...interface{})
|
Fatalln(args ...any)
|
||||||
// Fatalf logs to ERROR log. Arguments are handled in the manner of fmt.Printf.
|
// Fatalf logs to ERROR log. Arguments are handled in the manner of fmt.Printf.
|
||||||
// gRPC ensures that all Fatal logs will exit with os.Exit(1).
|
// gRPC ensures that all Fatal logs will exit with os.Exit(1).
|
||||||
// Implementations may also call os.Exit() with a non-zero exit code.
|
// Implementations may also call os.Exit() with a non-zero exit code.
|
||||||
Fatalf(format string, args ...interface{})
|
Fatalf(format string, args ...any)
|
||||||
// V reports whether verbosity level l is at least the requested verbose level.
|
// V reports whether verbosity level l is at least the requested verbose level.
|
||||||
V(l int) bool
|
V(l int) bool
|
||||||
}
|
}
|
||||||
@ -116,11 +116,11 @@ type LoggerV2 interface {
|
|||||||
// later release.
|
// later release.
|
||||||
type DepthLoggerV2 interface {
|
type DepthLoggerV2 interface {
|
||||||
// InfoDepth logs to INFO log at the specified depth. Arguments are handled in the manner of fmt.Println.
|
// InfoDepth logs to INFO log at the specified depth. Arguments are handled in the manner of fmt.Println.
|
||||||
InfoDepth(depth int, args ...interface{})
|
InfoDepth(depth int, args ...any)
|
||||||
// WarningDepth logs to WARNING log at the specified depth. Arguments are handled in the manner of fmt.Println.
|
// WarningDepth logs to WARNING log at the specified depth. Arguments are handled in the manner of fmt.Println.
|
||||||
WarningDepth(depth int, args ...interface{})
|
WarningDepth(depth int, args ...any)
|
||||||
// ErrorDepth logs to ERROR log at the specified depth. Arguments are handled in the manner of fmt.Println.
|
// ErrorDepth logs to ERROR log at the specified depth. Arguments are handled in the manner of fmt.Println.
|
||||||
ErrorDepth(depth int, args ...interface{})
|
ErrorDepth(depth int, args ...any)
|
||||||
// FatalDepth logs to FATAL log at the specified depth. Arguments are handled in the manner of fmt.Println.
|
// FatalDepth logs to FATAL log at the specified depth. Arguments are handled in the manner of fmt.Println.
|
||||||
FatalDepth(depth int, args ...interface{})
|
FatalDepth(depth int, args ...any)
|
||||||
}
|
}
|
||||||
|
20
vendor/google.golang.org/grpc/internal/grpclog/prefixLogger.go
generated
vendored
20
vendor/google.golang.org/grpc/internal/grpclog/prefixLogger.go
generated
vendored
@ -31,7 +31,7 @@ type PrefixLogger struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Infof does info logging.
|
// Infof does info logging.
|
||||||
func (pl *PrefixLogger) Infof(format string, args ...interface{}) {
|
func (pl *PrefixLogger) Infof(format string, args ...any) {
|
||||||
if pl != nil {
|
if pl != nil {
|
||||||
// Handle nil, so the tests can pass in a nil logger.
|
// Handle nil, so the tests can pass in a nil logger.
|
||||||
format = pl.prefix + format
|
format = pl.prefix + format
|
||||||
@ -42,7 +42,7 @@ func (pl *PrefixLogger) Infof(format string, args ...interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Warningf does warning logging.
|
// Warningf does warning logging.
|
||||||
func (pl *PrefixLogger) Warningf(format string, args ...interface{}) {
|
func (pl *PrefixLogger) Warningf(format string, args ...any) {
|
||||||
if pl != nil {
|
if pl != nil {
|
||||||
format = pl.prefix + format
|
format = pl.prefix + format
|
||||||
pl.logger.WarningDepth(1, fmt.Sprintf(format, args...))
|
pl.logger.WarningDepth(1, fmt.Sprintf(format, args...))
|
||||||
@ -52,7 +52,7 @@ func (pl *PrefixLogger) Warningf(format string, args ...interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Errorf does error logging.
|
// Errorf does error logging.
|
||||||
func (pl *PrefixLogger) Errorf(format string, args ...interface{}) {
|
func (pl *PrefixLogger) Errorf(format string, args ...any) {
|
||||||
if pl != nil {
|
if pl != nil {
|
||||||
format = pl.prefix + format
|
format = pl.prefix + format
|
||||||
pl.logger.ErrorDepth(1, fmt.Sprintf(format, args...))
|
pl.logger.ErrorDepth(1, fmt.Sprintf(format, args...))
|
||||||
@ -62,7 +62,10 @@ func (pl *PrefixLogger) Errorf(format string, args ...interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Debugf does info logging at verbose level 2.
|
// Debugf does info logging at verbose level 2.
|
||||||
func (pl *PrefixLogger) Debugf(format string, args ...interface{}) {
|
func (pl *PrefixLogger) Debugf(format string, args ...any) {
|
||||||
|
// TODO(6044): Refactor interfaces LoggerV2 and DepthLogger, and maybe
|
||||||
|
// rewrite PrefixLogger a little to ensure that we don't use the global
|
||||||
|
// `Logger` here, and instead use the `logger` field.
|
||||||
if !Logger.V(2) {
|
if !Logger.V(2) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -73,6 +76,15 @@ func (pl *PrefixLogger) Debugf(format string, args ...interface{}) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
InfoDepth(1, fmt.Sprintf(format, args...))
|
InfoDepth(1, fmt.Sprintf(format, args...))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// V reports whether verbosity level l is at least the requested verbose level.
|
||||||
|
func (pl *PrefixLogger) V(l int) bool {
|
||||||
|
// TODO(6044): Refactor interfaces LoggerV2 and DepthLogger, and maybe
|
||||||
|
// rewrite PrefixLogger a little to ensure that we don't use the global
|
||||||
|
// `Logger` here, and instead use the `logger` field.
|
||||||
|
return Logger.V(l)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPrefixLogger creates a prefix logger with the given prefix.
|
// NewPrefixLogger creates a prefix logger with the given prefix.
|
||||||
|
21
vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go
generated
vendored
21
vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go
generated
vendored
@ -72,3 +72,24 @@ func Uint64() uint64 {
|
|||||||
defer mu.Unlock()
|
defer mu.Unlock()
|
||||||
return r.Uint64()
|
return r.Uint64()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Uint32 implements rand.Uint32 on the grpcrand global source.
|
||||||
|
func Uint32() uint32 {
|
||||||
|
mu.Lock()
|
||||||
|
defer mu.Unlock()
|
||||||
|
return r.Uint32()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExpFloat64 implements rand.ExpFloat64 on the grpcrand global source.
|
||||||
|
func ExpFloat64() float64 {
|
||||||
|
mu.Lock()
|
||||||
|
defer mu.Unlock()
|
||||||
|
return r.ExpFloat64()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shuffle implements rand.Shuffle on the grpcrand global source.
|
||||||
|
var Shuffle = func(n int, f func(int, int)) {
|
||||||
|
mu.Lock()
|
||||||
|
defer mu.Unlock()
|
||||||
|
r.Shuffle(n, f)
|
||||||
|
}
|
||||||
|
125
vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go
generated
vendored
Normal file
125
vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go
generated
vendored
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* 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 grpcsync
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"google.golang.org/grpc/internal/buffer"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CallbackSerializer provides a mechanism to schedule callbacks in a
|
||||||
|
// synchronized manner. It provides a FIFO guarantee on the order of execution
|
||||||
|
// of scheduled callbacks. New callbacks can be scheduled by invoking the
|
||||||
|
// Schedule() method.
|
||||||
|
//
|
||||||
|
// This type is safe for concurrent access.
|
||||||
|
type CallbackSerializer struct {
|
||||||
|
// done is closed once the serializer is shut down completely, i.e all
|
||||||
|
// scheduled callbacks are executed and the serializer has deallocated all
|
||||||
|
// its resources.
|
||||||
|
done chan struct{}
|
||||||
|
|
||||||
|
callbacks *buffer.Unbounded
|
||||||
|
closedMu sync.Mutex
|
||||||
|
closed bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCallbackSerializer returns a new CallbackSerializer instance. The provided
|
||||||
|
// context will be passed to the scheduled callbacks. Users should cancel the
|
||||||
|
// provided context to shutdown the CallbackSerializer. It is guaranteed that no
|
||||||
|
// callbacks will be added once this context is canceled, and any pending un-run
|
||||||
|
// callbacks will be executed before the serializer is shut down.
|
||||||
|
func NewCallbackSerializer(ctx context.Context) *CallbackSerializer {
|
||||||
|
cs := &CallbackSerializer{
|
||||||
|
done: make(chan struct{}),
|
||||||
|
callbacks: buffer.NewUnbounded(),
|
||||||
|
}
|
||||||
|
go cs.run(ctx)
|
||||||
|
return cs
|
||||||
|
}
|
||||||
|
|
||||||
|
// Schedule adds a callback to be scheduled after existing callbacks are run.
|
||||||
|
//
|
||||||
|
// Callbacks are expected to honor the context when performing any blocking
|
||||||
|
// operations, and should return early when the context is canceled.
|
||||||
|
//
|
||||||
|
// Return value indicates if the callback was successfully added to the list of
|
||||||
|
// callbacks to be executed by the serializer. It is not possible to add
|
||||||
|
// callbacks once the context passed to NewCallbackSerializer is cancelled.
|
||||||
|
func (cs *CallbackSerializer) Schedule(f func(ctx context.Context)) bool {
|
||||||
|
cs.closedMu.Lock()
|
||||||
|
defer cs.closedMu.Unlock()
|
||||||
|
|
||||||
|
if cs.closed {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
cs.callbacks.Put(f)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cs *CallbackSerializer) run(ctx context.Context) {
|
||||||
|
var backlog []func(context.Context)
|
||||||
|
|
||||||
|
defer close(cs.done)
|
||||||
|
for ctx.Err() == nil {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
// Do nothing here. Next iteration of the for loop will not happen,
|
||||||
|
// since ctx.Err() would be non-nil.
|
||||||
|
case callback, ok := <-cs.callbacks.Get():
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cs.callbacks.Load()
|
||||||
|
callback.(func(ctx context.Context))(ctx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch pending callbacks if any, and execute them before returning from
|
||||||
|
// this method and closing cs.done.
|
||||||
|
cs.closedMu.Lock()
|
||||||
|
cs.closed = true
|
||||||
|
backlog = cs.fetchPendingCallbacks()
|
||||||
|
cs.callbacks.Close()
|
||||||
|
cs.closedMu.Unlock()
|
||||||
|
for _, b := range backlog {
|
||||||
|
b(ctx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cs *CallbackSerializer) fetchPendingCallbacks() []func(context.Context) {
|
||||||
|
var backlog []func(context.Context)
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case b := <-cs.callbacks.Get():
|
||||||
|
backlog = append(backlog, b.(func(context.Context)))
|
||||||
|
cs.callbacks.Load()
|
||||||
|
default:
|
||||||
|
return backlog
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Done returns a channel that is closed after the context passed to
|
||||||
|
// NewCallbackSerializer is canceled and all callbacks have been executed.
|
||||||
|
func (cs *CallbackSerializer) Done() <-chan struct{} {
|
||||||
|
return cs.done
|
||||||
|
}
|
121
vendor/google.golang.org/grpc/internal/grpcsync/pubsub.go
generated
vendored
Normal file
121
vendor/google.golang.org/grpc/internal/grpcsync/pubsub.go
generated
vendored
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2023 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 grpcsync
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Subscriber represents an entity that is subscribed to messages published on
|
||||||
|
// a PubSub. It wraps the callback to be invoked by the PubSub when a new
|
||||||
|
// message is published.
|
||||||
|
type Subscriber interface {
|
||||||
|
// OnMessage is invoked when a new message is published. Implementations
|
||||||
|
// must not block in this method.
|
||||||
|
OnMessage(msg any)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PubSub is a simple one-to-many publish-subscribe system that supports
|
||||||
|
// messages of arbitrary type. It guarantees that messages are delivered in
|
||||||
|
// the same order in which they were published.
|
||||||
|
//
|
||||||
|
// Publisher invokes the Publish() method to publish new messages, while
|
||||||
|
// subscribers interested in receiving these messages register a callback
|
||||||
|
// via the Subscribe() method.
|
||||||
|
//
|
||||||
|
// Once a PubSub is stopped, no more messages can be published, but any pending
|
||||||
|
// published messages will be delivered to the subscribers. Done may be used
|
||||||
|
// to determine when all published messages have been delivered.
|
||||||
|
type PubSub struct {
|
||||||
|
cs *CallbackSerializer
|
||||||
|
|
||||||
|
// Access to the below fields are guarded by this mutex.
|
||||||
|
mu sync.Mutex
|
||||||
|
msg any
|
||||||
|
subscribers map[Subscriber]bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPubSub returns a new PubSub instance. Users should cancel the
|
||||||
|
// provided context to shutdown the PubSub.
|
||||||
|
func NewPubSub(ctx context.Context) *PubSub {
|
||||||
|
return &PubSub{
|
||||||
|
cs: NewCallbackSerializer(ctx),
|
||||||
|
subscribers: map[Subscriber]bool{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subscribe registers the provided Subscriber to the PubSub.
|
||||||
|
//
|
||||||
|
// If the PubSub contains a previously published message, the Subscriber's
|
||||||
|
// OnMessage() callback will be invoked asynchronously with the existing
|
||||||
|
// message to begin with, and subsequently for every newly published message.
|
||||||
|
//
|
||||||
|
// The caller is responsible for invoking the returned cancel function to
|
||||||
|
// unsubscribe itself from the PubSub.
|
||||||
|
func (ps *PubSub) Subscribe(sub Subscriber) (cancel func()) {
|
||||||
|
ps.mu.Lock()
|
||||||
|
defer ps.mu.Unlock()
|
||||||
|
|
||||||
|
ps.subscribers[sub] = true
|
||||||
|
|
||||||
|
if ps.msg != nil {
|
||||||
|
msg := ps.msg
|
||||||
|
ps.cs.Schedule(func(context.Context) {
|
||||||
|
ps.mu.Lock()
|
||||||
|
defer ps.mu.Unlock()
|
||||||
|
if !ps.subscribers[sub] {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sub.OnMessage(msg)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return func() {
|
||||||
|
ps.mu.Lock()
|
||||||
|
defer ps.mu.Unlock()
|
||||||
|
delete(ps.subscribers, sub)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Publish publishes the provided message to the PubSub, and invokes
|
||||||
|
// callbacks registered by subscribers asynchronously.
|
||||||
|
func (ps *PubSub) Publish(msg any) {
|
||||||
|
ps.mu.Lock()
|
||||||
|
defer ps.mu.Unlock()
|
||||||
|
|
||||||
|
ps.msg = msg
|
||||||
|
for sub := range ps.subscribers {
|
||||||
|
s := sub
|
||||||
|
ps.cs.Schedule(func(context.Context) {
|
||||||
|
ps.mu.Lock()
|
||||||
|
defer ps.mu.Unlock()
|
||||||
|
if !ps.subscribers[s] {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.OnMessage(msg)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Done returns a channel that is closed after the context passed to NewPubSub
|
||||||
|
// is canceled and all updates have been sent to subscribers.
|
||||||
|
func (ps *PubSub) Done() <-chan struct{} {
|
||||||
|
return ps.cs.Done()
|
||||||
|
}
|
301
vendor/google.golang.org/grpc/internal/idle/idle.go
generated
vendored
Normal file
301
vendor/google.golang.org/grpc/internal/idle/idle.go
generated
vendored
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2023 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 idle contains a component for managing idleness (entering and exiting)
|
||||||
|
// based on RPC activity.
|
||||||
|
package idle
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"google.golang.org/grpc/grpclog"
|
||||||
|
)
|
||||||
|
|
||||||
|
// For overriding in unit tests.
|
||||||
|
var timeAfterFunc = func(d time.Duration, f func()) *time.Timer {
|
||||||
|
return time.AfterFunc(d, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enforcer is the functionality provided by grpc.ClientConn to enter
|
||||||
|
// and exit from idle mode.
|
||||||
|
type Enforcer interface {
|
||||||
|
ExitIdleMode() error
|
||||||
|
EnterIdleMode() error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Manager defines the functionality required to track RPC activity on a
|
||||||
|
// channel.
|
||||||
|
type Manager interface {
|
||||||
|
OnCallBegin() error
|
||||||
|
OnCallEnd()
|
||||||
|
Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
type noopManager struct{}
|
||||||
|
|
||||||
|
func (noopManager) OnCallBegin() error { return nil }
|
||||||
|
func (noopManager) OnCallEnd() {}
|
||||||
|
func (noopManager) Close() {}
|
||||||
|
|
||||||
|
// manager implements the Manager interface. It uses atomic operations to
|
||||||
|
// synchronize access to shared state and a mutex to guarantee mutual exclusion
|
||||||
|
// in a critical section.
|
||||||
|
type manager struct {
|
||||||
|
// State accessed atomically.
|
||||||
|
lastCallEndTime int64 // Unix timestamp in nanos; time when the most recent RPC completed.
|
||||||
|
activeCallsCount int32 // Count of active RPCs; -math.MaxInt32 means channel is idle or is trying to get there.
|
||||||
|
activeSinceLastTimerCheck int32 // Boolean; True if there was an RPC since the last timer callback.
|
||||||
|
closed int32 // Boolean; True when the manager is closed.
|
||||||
|
|
||||||
|
// Can be accessed without atomics or mutex since these are set at creation
|
||||||
|
// time and read-only after that.
|
||||||
|
enforcer Enforcer // Functionality provided by grpc.ClientConn.
|
||||||
|
timeout int64 // Idle timeout duration nanos stored as an int64.
|
||||||
|
logger grpclog.LoggerV2
|
||||||
|
|
||||||
|
// idleMu is used to guarantee mutual exclusion in two scenarios:
|
||||||
|
// - Opposing intentions:
|
||||||
|
// - a: Idle timeout has fired and handleIdleTimeout() is trying to put
|
||||||
|
// the channel in idle mode because the channel has been inactive.
|
||||||
|
// - b: At the same time an RPC is made on the channel, and OnCallBegin()
|
||||||
|
// is trying to prevent the channel from going idle.
|
||||||
|
// - Competing intentions:
|
||||||
|
// - The channel is in idle mode and there are multiple RPCs starting at
|
||||||
|
// the same time, all trying to move the channel out of idle. Only one
|
||||||
|
// of them should succeed in doing so, while the other RPCs should
|
||||||
|
// piggyback on the first one and be successfully handled.
|
||||||
|
idleMu sync.RWMutex
|
||||||
|
actuallyIdle bool
|
||||||
|
timer *time.Timer
|
||||||
|
}
|
||||||
|
|
||||||
|
// ManagerOptions is a collection of options used by
|
||||||
|
// NewManager.
|
||||||
|
type ManagerOptions struct {
|
||||||
|
Enforcer Enforcer
|
||||||
|
Timeout time.Duration
|
||||||
|
Logger grpclog.LoggerV2
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewManager creates a new idleness manager implementation for the
|
||||||
|
// given idle timeout.
|
||||||
|
func NewManager(opts ManagerOptions) Manager {
|
||||||
|
if opts.Timeout == 0 {
|
||||||
|
return noopManager{}
|
||||||
|
}
|
||||||
|
|
||||||
|
m := &manager{
|
||||||
|
enforcer: opts.Enforcer,
|
||||||
|
timeout: int64(opts.Timeout),
|
||||||
|
logger: opts.Logger,
|
||||||
|
}
|
||||||
|
m.timer = timeAfterFunc(opts.Timeout, m.handleIdleTimeout)
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
// resetIdleTimer resets the idle timer to the given duration. This method
|
||||||
|
// should only be called from the timer callback.
|
||||||
|
func (m *manager) resetIdleTimer(d time.Duration) {
|
||||||
|
m.idleMu.Lock()
|
||||||
|
defer m.idleMu.Unlock()
|
||||||
|
|
||||||
|
if m.timer == nil {
|
||||||
|
// Only close sets timer to nil. We are done.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// It is safe to ignore the return value from Reset() because this method is
|
||||||
|
// only ever called from the timer callback, which means the timer has
|
||||||
|
// already fired.
|
||||||
|
m.timer.Reset(d)
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleIdleTimeout is the timer callback that is invoked upon expiry of the
|
||||||
|
// configured idle timeout. The channel is considered inactive if there are no
|
||||||
|
// ongoing calls and no RPC activity since the last time the timer fired.
|
||||||
|
func (m *manager) handleIdleTimeout() {
|
||||||
|
if m.isClosed() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if atomic.LoadInt32(&m.activeCallsCount) > 0 {
|
||||||
|
m.resetIdleTimer(time.Duration(m.timeout))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// There has been activity on the channel since we last got here. Reset the
|
||||||
|
// timer and return.
|
||||||
|
if atomic.LoadInt32(&m.activeSinceLastTimerCheck) == 1 {
|
||||||
|
// Set the timer to fire after a duration of idle timeout, calculated
|
||||||
|
// from the time the most recent RPC completed.
|
||||||
|
atomic.StoreInt32(&m.activeSinceLastTimerCheck, 0)
|
||||||
|
m.resetIdleTimer(time.Duration(atomic.LoadInt64(&m.lastCallEndTime) + m.timeout - time.Now().UnixNano()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// This CAS operation is extremely likely to succeed given that there has
|
||||||
|
// been no activity since the last time we were here. Setting the
|
||||||
|
// activeCallsCount to -math.MaxInt32 indicates to OnCallBegin() that the
|
||||||
|
// channel is either in idle mode or is trying to get there.
|
||||||
|
if !atomic.CompareAndSwapInt32(&m.activeCallsCount, 0, -math.MaxInt32) {
|
||||||
|
// This CAS operation can fail if an RPC started after we checked for
|
||||||
|
// activity at the top of this method, or one was ongoing from before
|
||||||
|
// the last time we were here. In both case, reset the timer and return.
|
||||||
|
m.resetIdleTimer(time.Duration(m.timeout))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now that we've set the active calls count to -math.MaxInt32, it's time to
|
||||||
|
// actually move to idle mode.
|
||||||
|
if m.tryEnterIdleMode() {
|
||||||
|
// Successfully entered idle mode. No timer needed until we exit idle.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Failed to enter idle mode due to a concurrent RPC that kept the channel
|
||||||
|
// active, or because of an error from the channel. Undo the attempt to
|
||||||
|
// enter idle, and reset the timer to try again later.
|
||||||
|
atomic.AddInt32(&m.activeCallsCount, math.MaxInt32)
|
||||||
|
m.resetIdleTimer(time.Duration(m.timeout))
|
||||||
|
}
|
||||||
|
|
||||||
|
// tryEnterIdleMode instructs the channel to enter idle mode. But before
|
||||||
|
// that, it performs a last minute check to ensure that no new RPC has come in,
|
||||||
|
// making the channel active.
|
||||||
|
//
|
||||||
|
// Return value indicates whether or not the channel moved to idle mode.
|
||||||
|
//
|
||||||
|
// Holds idleMu which ensures mutual exclusion with exitIdleMode.
|
||||||
|
func (m *manager) tryEnterIdleMode() bool {
|
||||||
|
m.idleMu.Lock()
|
||||||
|
defer m.idleMu.Unlock()
|
||||||
|
|
||||||
|
if atomic.LoadInt32(&m.activeCallsCount) != -math.MaxInt32 {
|
||||||
|
// We raced and lost to a new RPC. Very rare, but stop entering idle.
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if atomic.LoadInt32(&m.activeSinceLastTimerCheck) == 1 {
|
||||||
|
// An very short RPC could have come in (and also finished) after we
|
||||||
|
// checked for calls count and activity in handleIdleTimeout(), but
|
||||||
|
// before the CAS operation. So, we need to check for activity again.
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// No new RPCs have come in since we last set the active calls count value
|
||||||
|
// -math.MaxInt32 in the timer callback. And since we have the lock, it is
|
||||||
|
// safe to enter idle mode now.
|
||||||
|
if err := m.enforcer.EnterIdleMode(); err != nil {
|
||||||
|
m.logger.Errorf("Failed to enter idle mode: %v", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Successfully entered idle mode.
|
||||||
|
m.actuallyIdle = true
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnCallBegin is invoked at the start of every RPC.
|
||||||
|
func (m *manager) OnCallBegin() error {
|
||||||
|
if m.isClosed() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if atomic.AddInt32(&m.activeCallsCount, 1) > 0 {
|
||||||
|
// Channel is not idle now. Set the activity bit and allow the call.
|
||||||
|
atomic.StoreInt32(&m.activeSinceLastTimerCheck, 1)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Channel is either in idle mode or is in the process of moving to idle
|
||||||
|
// mode. Attempt to exit idle mode to allow this RPC.
|
||||||
|
if err := m.exitIdleMode(); err != nil {
|
||||||
|
// Undo the increment to calls count, and return an error causing the
|
||||||
|
// RPC to fail.
|
||||||
|
atomic.AddInt32(&m.activeCallsCount, -1)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
atomic.StoreInt32(&m.activeSinceLastTimerCheck, 1)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// exitIdleMode instructs the channel to exit idle mode.
|
||||||
|
//
|
||||||
|
// Holds idleMu which ensures mutual exclusion with tryEnterIdleMode.
|
||||||
|
func (m *manager) exitIdleMode() error {
|
||||||
|
m.idleMu.Lock()
|
||||||
|
defer m.idleMu.Unlock()
|
||||||
|
|
||||||
|
if !m.actuallyIdle {
|
||||||
|
// This can happen in two scenarios:
|
||||||
|
// - handleIdleTimeout() set the calls count to -math.MaxInt32 and called
|
||||||
|
// tryEnterIdleMode(). But before the latter could grab the lock, an RPC
|
||||||
|
// came in and OnCallBegin() noticed that the calls count is negative.
|
||||||
|
// - Channel is in idle mode, and multiple new RPCs come in at the same
|
||||||
|
// time, all of them notice a negative calls count in OnCallBegin and get
|
||||||
|
// here. The first one to get the lock would got the channel to exit idle.
|
||||||
|
//
|
||||||
|
// Either way, nothing to do here.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.enforcer.ExitIdleMode(); err != nil {
|
||||||
|
return fmt.Errorf("channel failed to exit idle mode: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Undo the idle entry process. This also respects any new RPC attempts.
|
||||||
|
atomic.AddInt32(&m.activeCallsCount, math.MaxInt32)
|
||||||
|
m.actuallyIdle = false
|
||||||
|
|
||||||
|
// Start a new timer to fire after the configured idle timeout.
|
||||||
|
m.timer = timeAfterFunc(time.Duration(m.timeout), m.handleIdleTimeout)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnCallEnd is invoked at the end of every RPC.
|
||||||
|
func (m *manager) OnCallEnd() {
|
||||||
|
if m.isClosed() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Record the time at which the most recent call finished.
|
||||||
|
atomic.StoreInt64(&m.lastCallEndTime, time.Now().UnixNano())
|
||||||
|
|
||||||
|
// Decrement the active calls count. This count can temporarily go negative
|
||||||
|
// when the timer callback is in the process of moving the channel to idle
|
||||||
|
// mode, but one or more RPCs come in and complete before the timer callback
|
||||||
|
// can get done with the process of moving to idle mode.
|
||||||
|
atomic.AddInt32(&m.activeCallsCount, -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *manager) isClosed() bool {
|
||||||
|
return atomic.LoadInt32(&m.closed) == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *manager) Close() {
|
||||||
|
atomic.StoreInt32(&m.closed, 1)
|
||||||
|
|
||||||
|
m.idleMu.Lock()
|
||||||
|
m.timer.Stop()
|
||||||
|
m.timer = nil
|
||||||
|
m.idleMu.Unlock()
|
||||||
|
}
|
73
vendor/google.golang.org/grpc/internal/internal.go
generated
vendored
73
vendor/google.golang.org/grpc/internal/internal.go
generated
vendored
@ -30,7 +30,7 @@ import (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
// WithHealthCheckFunc is set by dialoptions.go
|
// WithHealthCheckFunc is set by dialoptions.go
|
||||||
WithHealthCheckFunc interface{} // func (HealthChecker) DialOption
|
WithHealthCheckFunc any // func (HealthChecker) DialOption
|
||||||
// HealthCheckFunc is used to provide client-side LB channel health checking
|
// HealthCheckFunc is used to provide client-side LB channel health checking
|
||||||
HealthCheckFunc HealthChecker
|
HealthCheckFunc HealthChecker
|
||||||
// BalancerUnregister is exported by package balancer to unregister a balancer.
|
// BalancerUnregister is exported by package balancer to unregister a balancer.
|
||||||
@ -38,8 +38,12 @@ var (
|
|||||||
// KeepaliveMinPingTime is the minimum ping interval. This must be 10s by
|
// KeepaliveMinPingTime is the minimum ping interval. This must be 10s by
|
||||||
// default, but tests may wish to set it lower for convenience.
|
// default, but tests may wish to set it lower for convenience.
|
||||||
KeepaliveMinPingTime = 10 * time.Second
|
KeepaliveMinPingTime = 10 * time.Second
|
||||||
|
// KeepaliveMinServerPingTime is the minimum ping interval for servers.
|
||||||
|
// This must be 1s by default, but tests may wish to set it lower for
|
||||||
|
// convenience.
|
||||||
|
KeepaliveMinServerPingTime = time.Second
|
||||||
// ParseServiceConfig parses a JSON representation of the service config.
|
// ParseServiceConfig parses a JSON representation of the service config.
|
||||||
ParseServiceConfig interface{} // func(string) *serviceconfig.ParseResult
|
ParseServiceConfig any // func(string) *serviceconfig.ParseResult
|
||||||
// EqualServiceConfigForTesting is for testing service config generation and
|
// EqualServiceConfigForTesting is for testing service config generation and
|
||||||
// parsing. Both a and b should be returned by ParseServiceConfig.
|
// parsing. Both a and b should be returned by ParseServiceConfig.
|
||||||
// This function compares the config without rawJSON stripped, in case the
|
// This function compares the config without rawJSON stripped, in case the
|
||||||
@ -49,47 +53,81 @@ var (
|
|||||||
// given name. This is set by package certprovider for use from xDS
|
// given name. This is set by package certprovider for use from xDS
|
||||||
// bootstrap code while parsing certificate provider configs in the
|
// bootstrap code while parsing certificate provider configs in the
|
||||||
// bootstrap file.
|
// bootstrap file.
|
||||||
GetCertificateProviderBuilder interface{} // func(string) certprovider.Builder
|
GetCertificateProviderBuilder any // func(string) certprovider.Builder
|
||||||
// GetXDSHandshakeInfoForTesting returns a pointer to the xds.HandshakeInfo
|
// GetXDSHandshakeInfoForTesting returns a pointer to the xds.HandshakeInfo
|
||||||
// stored in the passed in attributes. This is set by
|
// stored in the passed in attributes. This is set by
|
||||||
// credentials/xds/xds.go.
|
// credentials/xds/xds.go.
|
||||||
GetXDSHandshakeInfoForTesting interface{} // func (*attributes.Attributes) *xds.HandshakeInfo
|
GetXDSHandshakeInfoForTesting any // func (*attributes.Attributes) *xds.HandshakeInfo
|
||||||
// GetServerCredentials returns the transport credentials configured on a
|
// GetServerCredentials returns the transport credentials configured on a
|
||||||
// gRPC server. An xDS-enabled server needs to know what type of credentials
|
// gRPC server. An xDS-enabled server needs to know what type of credentials
|
||||||
// is configured on the underlying gRPC server. This is set by server.go.
|
// is configured on the underlying gRPC server. This is set by server.go.
|
||||||
GetServerCredentials interface{} // func (*grpc.Server) credentials.TransportCredentials
|
GetServerCredentials any // func (*grpc.Server) credentials.TransportCredentials
|
||||||
|
// CanonicalString returns the canonical string of the code defined here:
|
||||||
|
// https://github.com/grpc/grpc/blob/master/doc/statuscodes.md.
|
||||||
|
//
|
||||||
|
// This is used in the 1.0 release of gcp/observability, and thus must not be
|
||||||
|
// deleted or changed.
|
||||||
|
CanonicalString any // func (codes.Code) string
|
||||||
// DrainServerTransports initiates a graceful close of existing connections
|
// DrainServerTransports initiates a graceful close of existing connections
|
||||||
// on a gRPC server accepted on the provided listener address. An
|
// on a gRPC server accepted on the provided listener address. An
|
||||||
// xDS-enabled server invokes this method on a grpc.Server when a particular
|
// xDS-enabled server invokes this method on a grpc.Server when a particular
|
||||||
// listener moves to "not-serving" mode.
|
// listener moves to "not-serving" mode.
|
||||||
DrainServerTransports interface{} // func(*grpc.Server, string)
|
DrainServerTransports any // func(*grpc.Server, string)
|
||||||
// AddGlobalServerOptions adds an array of ServerOption that will be
|
// AddGlobalServerOptions adds an array of ServerOption that will be
|
||||||
// effective globally for newly created servers. The priority will be: 1.
|
// effective globally for newly created servers. The priority will be: 1.
|
||||||
// user-provided; 2. this method; 3. default values.
|
// user-provided; 2. this method; 3. default values.
|
||||||
AddGlobalServerOptions interface{} // func(opt ...ServerOption)
|
//
|
||||||
|
// This is used in the 1.0 release of gcp/observability, and thus must not be
|
||||||
|
// deleted or changed.
|
||||||
|
AddGlobalServerOptions any // func(opt ...ServerOption)
|
||||||
// ClearGlobalServerOptions clears the array of extra ServerOption. This
|
// ClearGlobalServerOptions clears the array of extra ServerOption. This
|
||||||
// method is useful in testing and benchmarking.
|
// method is useful in testing and benchmarking.
|
||||||
|
//
|
||||||
|
// This is used in the 1.0 release of gcp/observability, and thus must not be
|
||||||
|
// deleted or changed.
|
||||||
ClearGlobalServerOptions func()
|
ClearGlobalServerOptions func()
|
||||||
// AddGlobalDialOptions adds an array of DialOption that will be effective
|
// AddGlobalDialOptions adds an array of DialOption that will be effective
|
||||||
// globally for newly created client channels. The priority will be: 1.
|
// globally for newly created client channels. The priority will be: 1.
|
||||||
// user-provided; 2. this method; 3. default values.
|
// user-provided; 2. this method; 3. default values.
|
||||||
AddGlobalDialOptions interface{} // func(opt ...DialOption)
|
//
|
||||||
|
// This is used in the 1.0 release of gcp/observability, and thus must not be
|
||||||
|
// deleted or changed.
|
||||||
|
AddGlobalDialOptions any // func(opt ...DialOption)
|
||||||
|
// DisableGlobalDialOptions returns a DialOption that prevents the
|
||||||
|
// ClientConn from applying the global DialOptions (set via
|
||||||
|
// AddGlobalDialOptions).
|
||||||
|
//
|
||||||
|
// This is used in the 1.0 release of gcp/observability, and thus must not be
|
||||||
|
// deleted or changed.
|
||||||
|
DisableGlobalDialOptions any // func() grpc.DialOption
|
||||||
// ClearGlobalDialOptions clears the array of extra DialOption. This
|
// ClearGlobalDialOptions clears the array of extra DialOption. This
|
||||||
// method is useful in testing and benchmarking.
|
// method is useful in testing and benchmarking.
|
||||||
|
//
|
||||||
|
// This is used in the 1.0 release of gcp/observability, and thus must not be
|
||||||
|
// deleted or changed.
|
||||||
ClearGlobalDialOptions func()
|
ClearGlobalDialOptions func()
|
||||||
// JoinDialOptions combines the dial options passed as arguments into a
|
// JoinDialOptions combines the dial options passed as arguments into a
|
||||||
// single dial option.
|
// single dial option.
|
||||||
JoinDialOptions interface{} // func(...grpc.DialOption) grpc.DialOption
|
JoinDialOptions any // func(...grpc.DialOption) grpc.DialOption
|
||||||
// JoinServerOptions combines the server options passed as arguments into a
|
// JoinServerOptions combines the server options passed as arguments into a
|
||||||
// single server option.
|
// single server option.
|
||||||
JoinServerOptions interface{} // func(...grpc.ServerOption) grpc.ServerOption
|
JoinServerOptions any // func(...grpc.ServerOption) grpc.ServerOption
|
||||||
|
|
||||||
// WithBinaryLogger returns a DialOption that specifies the binary logger
|
// WithBinaryLogger returns a DialOption that specifies the binary logger
|
||||||
// for a ClientConn.
|
// for a ClientConn.
|
||||||
WithBinaryLogger interface{} // func(binarylog.Logger) grpc.DialOption
|
//
|
||||||
|
// This is used in the 1.0 release of gcp/observability, and thus must not be
|
||||||
|
// deleted or changed.
|
||||||
|
WithBinaryLogger any // func(binarylog.Logger) grpc.DialOption
|
||||||
// BinaryLogger returns a ServerOption that can set the binary logger for a
|
// BinaryLogger returns a ServerOption that can set the binary logger for a
|
||||||
// server.
|
// server.
|
||||||
BinaryLogger interface{} // func(binarylog.Logger) grpc.ServerOption
|
//
|
||||||
|
// This is used in the 1.0 release of gcp/observability, and thus must not be
|
||||||
|
// deleted or changed.
|
||||||
|
BinaryLogger any // func(binarylog.Logger) grpc.ServerOption
|
||||||
|
|
||||||
|
// SubscribeToConnectivityStateChanges adds a grpcsync.Subscriber to a provided grpc.ClientConn
|
||||||
|
SubscribeToConnectivityStateChanges any // func(*grpc.ClientConn, grpcsync.Subscriber)
|
||||||
|
|
||||||
// NewXDSResolverWithConfigForTesting creates a new xds resolver builder using
|
// NewXDSResolverWithConfigForTesting creates a new xds resolver builder using
|
||||||
// the provided xds bootstrap config instead of the global configuration from
|
// the provided xds bootstrap config instead of the global configuration from
|
||||||
@ -100,7 +138,7 @@ var (
|
|||||||
//
|
//
|
||||||
// This function should ONLY be used for testing and may not work with some
|
// This function should ONLY be used for testing and may not work with some
|
||||||
// other features, including the CSDS service.
|
// other features, including the CSDS service.
|
||||||
NewXDSResolverWithConfigForTesting interface{} // func([]byte) (resolver.Builder, error)
|
NewXDSResolverWithConfigForTesting any // func([]byte) (resolver.Builder, error)
|
||||||
|
|
||||||
// RegisterRLSClusterSpecifierPluginForTesting registers the RLS Cluster
|
// RegisterRLSClusterSpecifierPluginForTesting registers the RLS Cluster
|
||||||
// Specifier Plugin for testing purposes, regardless of the XDSRLS environment
|
// Specifier Plugin for testing purposes, regardless of the XDSRLS environment
|
||||||
@ -130,6 +168,13 @@ var (
|
|||||||
//
|
//
|
||||||
// TODO: Remove this function once the RBAC env var is removed.
|
// TODO: Remove this function once the RBAC env var is removed.
|
||||||
UnregisterRBACHTTPFilterForTesting func()
|
UnregisterRBACHTTPFilterForTesting func()
|
||||||
|
|
||||||
|
// ORCAAllowAnyMinReportingInterval is for examples/orca use ONLY.
|
||||||
|
ORCAAllowAnyMinReportingInterval any // func(so *orca.ServiceOptions)
|
||||||
|
|
||||||
|
// GRPCResolverSchemeExtraMetadata determines when gRPC will add extra
|
||||||
|
// metadata to RPCs.
|
||||||
|
GRPCResolverSchemeExtraMetadata string = "xds"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HealthChecker defines the signature of the client-side LB channel health checking function.
|
// HealthChecker defines the signature of the client-side LB channel health checking function.
|
||||||
@ -140,7 +185,7 @@ var (
|
|||||||
//
|
//
|
||||||
// The health checking protocol is defined at:
|
// The health checking protocol is defined at:
|
||||||
// https://github.com/grpc/grpc/blob/master/doc/health-checking.md
|
// https://github.com/grpc/grpc/blob/master/doc/health-checking.md
|
||||||
type HealthChecker func(ctx context.Context, newStream func(string) (interface{}, error), setConnectivityState func(connectivity.State, error), serviceName string) error
|
type HealthChecker func(ctx context.Context, newStream func(string) (any, error), setConnectivityState func(connectivity.State, error), serviceName string) error
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// CredsBundleModeFallback switches GoogleDefaultCreds to fallback mode.
|
// CredsBundleModeFallback switches GoogleDefaultCreds to fallback mode.
|
||||||
|
64
vendor/google.golang.org/grpc/internal/metadata/metadata.go
generated
vendored
64
vendor/google.golang.org/grpc/internal/metadata/metadata.go
generated
vendored
@ -35,7 +35,7 @@ const mdKey = mdKeyType("grpc.internal.address.metadata")
|
|||||||
|
|
||||||
type mdValue metadata.MD
|
type mdValue metadata.MD
|
||||||
|
|
||||||
func (m mdValue) Equal(o interface{}) bool {
|
func (m mdValue) Equal(o any) bool {
|
||||||
om, ok := o.(mdValue)
|
om, ok := o.(mdValue)
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
@ -76,33 +76,11 @@ func Set(addr resolver.Address, md metadata.MD) resolver.Address {
|
|||||||
return addr
|
return addr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate returns an error if the input md contains invalid keys or values.
|
// Validate validates every pair in md with ValidatePair.
|
||||||
//
|
|
||||||
// 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 {
|
func Validate(md metadata.MD) error {
|
||||||
for k, vals := range md {
|
for k, vals := range md {
|
||||||
// pseudo-header will be ignored
|
if err := ValidatePair(k, vals...); err != nil {
|
||||||
if k[0] == ':' {
|
return err
|
||||||
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
|
return nil
|
||||||
@ -118,3 +96,37 @@ func hasNotPrintable(msg string) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ValidatePair validate a key-value pair with the following rules (the pseudo-header will be skipped) :
|
||||||
|
//
|
||||||
|
// - key must contain one or more characters.
|
||||||
|
// - the characters in the key must be contained in [0-9 a-z _ - .].
|
||||||
|
// - if the key ends with a "-bin" suffix, no validation of the corresponding value is performed.
|
||||||
|
// - the characters in the every value must be printable (in [%x20-%x7E]).
|
||||||
|
func ValidatePair(key string, vals ...string) error {
|
||||||
|
// key should not be empty
|
||||||
|
if key == "" {
|
||||||
|
return fmt.Errorf("there is an empty key in the header")
|
||||||
|
}
|
||||||
|
// pseudo-header will be ignored
|
||||||
|
if key[0] == ':' {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// check key, for i that saving a conversion if not using for range
|
||||||
|
for i := 0; i < len(key); i++ {
|
||||||
|
r := key[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-_.]", key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if strings.HasSuffix(key, "-bin") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// check value
|
||||||
|
for _, val := range vals {
|
||||||
|
if hasNotPrintable(val) {
|
||||||
|
return fmt.Errorf("header key %q contains value with non-printable ASCII characters", key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
2
vendor/google.golang.org/grpc/internal/pretty/pretty.go
generated
vendored
2
vendor/google.golang.org/grpc/internal/pretty/pretty.go
generated
vendored
@ -35,7 +35,7 @@ const jsonIndent = " "
|
|||||||
// ToJSON marshals the input into a json string.
|
// ToJSON marshals the input into a json string.
|
||||||
//
|
//
|
||||||
// If marshal fails, it falls back to fmt.Sprintf("%+v").
|
// If marshal fails, it falls back to fmt.Sprintf("%+v").
|
||||||
func ToJSON(e interface{}) string {
|
func ToJSON(e any) string {
|
||||||
switch ee := e.(type) {
|
switch ee := e.(type) {
|
||||||
case protov1.Message:
|
case protov1.Message:
|
||||||
mm := jsonpb.Marshaler{Indent: jsonIndent}
|
mm := jsonpb.Marshaler{Indent: jsonIndent}
|
||||||
|
4
vendor/google.golang.org/grpc/internal/resolver/config_selector.go
generated
vendored
4
vendor/google.golang.org/grpc/internal/resolver/config_selector.go
generated
vendored
@ -92,7 +92,7 @@ type ClientStream interface {
|
|||||||
// calling RecvMsg on the same stream at the same time, but it is not safe
|
// calling RecvMsg on the same stream at the same time, but it is not safe
|
||||||
// to call SendMsg on the same stream in different goroutines. It is also
|
// to call SendMsg on the same stream in different goroutines. It is also
|
||||||
// not safe to call CloseSend concurrently with SendMsg.
|
// not safe to call CloseSend concurrently with SendMsg.
|
||||||
SendMsg(m interface{}) error
|
SendMsg(m any) error
|
||||||
// RecvMsg blocks until it receives a message into m or the stream is
|
// RecvMsg blocks until it receives a message into m or the stream is
|
||||||
// done. It returns io.EOF when the stream completes successfully. On
|
// done. It returns io.EOF when the stream completes successfully. On
|
||||||
// any other error, the stream is aborted and the error contains the RPC
|
// any other error, the stream is aborted and the error contains the RPC
|
||||||
@ -101,7 +101,7 @@ type ClientStream interface {
|
|||||||
// It is safe to have a goroutine calling SendMsg and another goroutine
|
// It is safe to have a goroutine calling SendMsg and another goroutine
|
||||||
// calling RecvMsg on the same stream at the same time, but it is not
|
// calling RecvMsg on the same stream at the same time, but it is not
|
||||||
// safe to call RecvMsg on the same stream in different goroutines.
|
// safe to call RecvMsg on the same stream in different goroutines.
|
||||||
RecvMsg(m interface{}) error
|
RecvMsg(m any) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClientInterceptor is an interceptor for gRPC client streams.
|
// ClientInterceptor is an interceptor for gRPC client streams.
|
||||||
|
74
vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go
generated
vendored
74
vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go
generated
vendored
@ -62,7 +62,8 @@ const (
|
|||||||
defaultPort = "443"
|
defaultPort = "443"
|
||||||
defaultDNSSvrPort = "53"
|
defaultDNSSvrPort = "53"
|
||||||
golang = "GO"
|
golang = "GO"
|
||||||
// txtPrefix is the prefix string to be prepended to the host name for txt record lookup.
|
// txtPrefix is the prefix string to be prepended to the host name for txt
|
||||||
|
// record lookup.
|
||||||
txtPrefix = "_grpc_config."
|
txtPrefix = "_grpc_config."
|
||||||
// In DNS, service config is encoded in a TXT record via the mechanism
|
// In DNS, service config is encoded in a TXT record via the mechanism
|
||||||
// described in RFC-1464 using the attribute name grpc_config.
|
// described in RFC-1464 using the attribute name grpc_config.
|
||||||
@ -86,14 +87,14 @@ var (
|
|||||||
minDNSResRate = 30 * time.Second
|
minDNSResRate = 30 * time.Second
|
||||||
)
|
)
|
||||||
|
|
||||||
var customAuthorityDialler = func(authority string) func(ctx context.Context, network, address string) (net.Conn, error) {
|
var addressDialer = func(address string) func(context.Context, string, string) (net.Conn, error) {
|
||||||
return func(ctx context.Context, network, address string) (net.Conn, error) {
|
return func(ctx context.Context, network, _ string) (net.Conn, error) {
|
||||||
var dialer net.Dialer
|
var dialer net.Dialer
|
||||||
return dialer.DialContext(ctx, network, authority)
|
return dialer.DialContext(ctx, network, address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var customAuthorityResolver = func(authority string) (netResolver, error) {
|
var newNetResolver = func(authority string) (netResolver, error) {
|
||||||
host, port, err := parseTarget(authority, defaultDNSSvrPort)
|
host, port, err := parseTarget(authority, defaultDNSSvrPort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -103,7 +104,7 @@ var customAuthorityResolver = func(authority string) (netResolver, error) {
|
|||||||
|
|
||||||
return &net.Resolver{
|
return &net.Resolver{
|
||||||
PreferGo: true,
|
PreferGo: true,
|
||||||
Dial: customAuthorityDialler(authorityWithPort),
|
Dial: addressDialer(authorityWithPort),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +115,8 @@ func NewBuilder() resolver.Builder {
|
|||||||
|
|
||||||
type dnsBuilder struct{}
|
type dnsBuilder struct{}
|
||||||
|
|
||||||
// Build creates and starts a DNS resolver that watches the name resolution of the target.
|
// Build creates and starts a DNS resolver that watches the name resolution of
|
||||||
|
// the target.
|
||||||
func (b *dnsBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) {
|
func (b *dnsBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) {
|
||||||
host, port, err := parseTarget(target.Endpoint(), defaultPort)
|
host, port, err := parseTarget(target.Endpoint(), defaultPort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -143,7 +145,7 @@ func (b *dnsBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts
|
|||||||
if target.URL.Host == "" {
|
if target.URL.Host == "" {
|
||||||
d.resolver = defaultResolver
|
d.resolver = defaultResolver
|
||||||
} else {
|
} else {
|
||||||
d.resolver, err = customAuthorityResolver(target.URL.Host)
|
d.resolver, err = newNetResolver(target.URL.Host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -180,19 +182,22 @@ type dnsResolver struct {
|
|||||||
ctx context.Context
|
ctx context.Context
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
cc resolver.ClientConn
|
cc resolver.ClientConn
|
||||||
// rn channel is used by ResolveNow() to force an immediate resolution of the target.
|
// rn channel is used by ResolveNow() to force an immediate resolution of the
|
||||||
|
// target.
|
||||||
rn chan struct{}
|
rn chan struct{}
|
||||||
// wg is used to enforce Close() to return after the watcher() goroutine has finished.
|
// wg is used to enforce Close() to return after the watcher() goroutine has
|
||||||
// Otherwise, data race will be possible. [Race Example] in dns_resolver_test we
|
// finished. Otherwise, data race will be possible. [Race Example] in
|
||||||
// replace the real lookup functions with mocked ones to facilitate testing.
|
// dns_resolver_test we replace the real lookup functions with mocked ones to
|
||||||
// If Close() doesn't wait for watcher() goroutine finishes, race detector sometimes
|
// facilitate testing. If Close() doesn't wait for watcher() goroutine
|
||||||
// will warns lookup (READ the lookup function pointers) inside watcher() goroutine
|
// finishes, race detector sometimes will warns lookup (READ the lookup
|
||||||
// has data race with replaceNetFunc (WRITE the lookup function pointers).
|
// function pointers) inside watcher() goroutine has data race with
|
||||||
|
// replaceNetFunc (WRITE the lookup function pointers).
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
disableServiceConfig bool
|
disableServiceConfig bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResolveNow invoke an immediate resolution of the target that this dnsResolver watches.
|
// ResolveNow invoke an immediate resolution of the target that this
|
||||||
|
// dnsResolver watches.
|
||||||
func (d *dnsResolver) ResolveNow(resolver.ResolveNowOptions) {
|
func (d *dnsResolver) ResolveNow(resolver.ResolveNowOptions) {
|
||||||
select {
|
select {
|
||||||
case d.rn <- struct{}{}:
|
case d.rn <- struct{}{}:
|
||||||
@ -220,8 +225,8 @@ func (d *dnsResolver) watcher() {
|
|||||||
|
|
||||||
var timer *time.Timer
|
var timer *time.Timer
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// Success resolving, wait for the next ResolveNow. However, also wait 30 seconds at the very least
|
// Success resolving, wait for the next ResolveNow. However, also wait 30
|
||||||
// to prevent constantly re-resolving.
|
// seconds at the very least to prevent constantly re-resolving.
|
||||||
backoffIndex = 1
|
backoffIndex = 1
|
||||||
timer = newTimerDNSResRate(minDNSResRate)
|
timer = newTimerDNSResRate(minDNSResRate)
|
||||||
select {
|
select {
|
||||||
@ -231,7 +236,8 @@ func (d *dnsResolver) watcher() {
|
|||||||
case <-d.rn:
|
case <-d.rn:
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Poll on an error found in DNS Resolver or an error received from ClientConn.
|
// Poll on an error found in DNS Resolver or an error received from
|
||||||
|
// ClientConn.
|
||||||
timer = newTimer(backoff.DefaultExponential.Backoff(backoffIndex))
|
timer = newTimer(backoff.DefaultExponential.Backoff(backoffIndex))
|
||||||
backoffIndex++
|
backoffIndex++
|
||||||
}
|
}
|
||||||
@ -278,7 +284,8 @@ func (d *dnsResolver) lookupSRV() ([]resolver.Address, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func handleDNSError(err error, lookupType string) error {
|
func handleDNSError(err error, lookupType string) error {
|
||||||
if dnsErr, ok := err.(*net.DNSError); ok && !dnsErr.IsTimeout && !dnsErr.IsTemporary {
|
dnsErr, ok := err.(*net.DNSError)
|
||||||
|
if ok && !dnsErr.IsTimeout && !dnsErr.IsTemporary {
|
||||||
// Timeouts and temporary errors should be communicated to gRPC to
|
// Timeouts and temporary errors should be communicated to gRPC to
|
||||||
// attempt another DNS query (with backoff). Other errors should be
|
// attempt another DNS query (with backoff). Other errors should be
|
||||||
// suppressed (they may represent the absence of a TXT record).
|
// suppressed (they may represent the absence of a TXT record).
|
||||||
@ -307,10 +314,12 @@ func (d *dnsResolver) lookupTXT() *serviceconfig.ParseResult {
|
|||||||
res += s
|
res += s
|
||||||
}
|
}
|
||||||
|
|
||||||
// TXT record must have "grpc_config=" attribute in order to be used as service config.
|
// TXT record must have "grpc_config=" attribute in order to be used as
|
||||||
|
// service config.
|
||||||
if !strings.HasPrefix(res, txtAttribute) {
|
if !strings.HasPrefix(res, txtAttribute) {
|
||||||
logger.Warningf("dns: TXT record %v missing %v attribute", res, txtAttribute)
|
logger.Warningf("dns: TXT record %v missing %v attribute", res, txtAttribute)
|
||||||
// This is not an error; it is the equivalent of not having a service config.
|
// This is not an error; it is the equivalent of not having a service
|
||||||
|
// config.
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
sc := canaryingSC(strings.TrimPrefix(res, txtAttribute))
|
sc := canaryingSC(strings.TrimPrefix(res, txtAttribute))
|
||||||
@ -352,9 +361,10 @@ func (d *dnsResolver) lookup() (*resolver.State, error) {
|
|||||||
return &state, nil
|
return &state, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// formatIP returns ok = false if addr is not a valid textual representation of an IP address.
|
// formatIP returns ok = false if addr is not a valid textual representation of
|
||||||
// If addr is an IPv4 address, return the addr and ok = true.
|
// an IP address. If addr is an IPv4 address, return the addr and ok = true.
|
||||||
// If addr is an IPv6 address, return the addr enclosed in square brackets and ok = true.
|
// If addr is an IPv6 address, return the addr enclosed in square brackets and
|
||||||
|
// ok = true.
|
||||||
func formatIP(addr string) (addrIP string, ok bool) {
|
func formatIP(addr string) (addrIP string, ok bool) {
|
||||||
ip := net.ParseIP(addr)
|
ip := net.ParseIP(addr)
|
||||||
if ip == nil {
|
if ip == nil {
|
||||||
@ -366,10 +376,10 @@ func formatIP(addr string) (addrIP string, ok bool) {
|
|||||||
return "[" + addr + "]", true
|
return "[" + addr + "]", true
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseTarget takes the user input target string and default port, returns formatted host and port info.
|
// parseTarget takes the user input target string and default port, returns
|
||||||
// If target doesn't specify a port, set the port to be the defaultPort.
|
// formatted host and port info. If target doesn't specify a port, set the port
|
||||||
// If target is in IPv6 format and host-name is enclosed in square brackets, brackets
|
// to be the defaultPort. If target is in IPv6 format and host-name is enclosed
|
||||||
// are stripped when setting the host.
|
// in square brackets, brackets are stripped when setting the host.
|
||||||
// examples:
|
// examples:
|
||||||
// target: "www.google.com" defaultPort: "443" returns host: "www.google.com", port: "443"
|
// target: "www.google.com" defaultPort: "443" returns host: "www.google.com", port: "443"
|
||||||
// target: "ipv4-host:80" defaultPort: "443" returns host: "ipv4-host", port: "80"
|
// target: "ipv4-host:80" defaultPort: "443" returns host: "ipv4-host", port: "80"
|
||||||
@ -385,12 +395,14 @@ func parseTarget(target, defaultPort string) (host, port string, err error) {
|
|||||||
}
|
}
|
||||||
if host, port, err = net.SplitHostPort(target); err == nil {
|
if host, port, err = net.SplitHostPort(target); err == nil {
|
||||||
if port == "" {
|
if port == "" {
|
||||||
// If the port field is empty (target ends with colon), e.g. "[::1]:", this is an error.
|
// If the port field is empty (target ends with colon), e.g. "[::1]:",
|
||||||
|
// this is an error.
|
||||||
return "", "", errEndsWithColon
|
return "", "", errEndsWithColon
|
||||||
}
|
}
|
||||||
// target has port, i.e ipv4-host:port, [ipv6-host]:port, host-name:port
|
// target has port, i.e ipv4-host:port, [ipv6-host]:port, host-name:port
|
||||||
if host == "" {
|
if host == "" {
|
||||||
// Keep consistent with net.Dial(): If the host is empty, as in ":80", the local system is assumed.
|
// Keep consistent with net.Dial(): If the host is empty, as in ":80",
|
||||||
|
// the local system is assumed.
|
||||||
host = "localhost"
|
host = "localhost"
|
||||||
}
|
}
|
||||||
return host, port, nil
|
return host, port, nil
|
||||||
|
130
vendor/google.golang.org/grpc/internal/serviceconfig/duration.go
generated
vendored
Normal file
130
vendor/google.golang.org/grpc/internal/serviceconfig/duration.go
generated
vendored
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2023 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 serviceconfig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Duration defines JSON marshal and unmarshal methods to conform to the
|
||||||
|
// protobuf JSON spec defined [here].
|
||||||
|
//
|
||||||
|
// [here]: https://protobuf.dev/reference/protobuf/google.protobuf/#duration
|
||||||
|
type Duration time.Duration
|
||||||
|
|
||||||
|
func (d Duration) String() string {
|
||||||
|
return fmt.Sprint(time.Duration(d))
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON converts from d to a JSON string output.
|
||||||
|
func (d Duration) MarshalJSON() ([]byte, error) {
|
||||||
|
ns := time.Duration(d).Nanoseconds()
|
||||||
|
sec := ns / int64(time.Second)
|
||||||
|
ns = ns % int64(time.Second)
|
||||||
|
|
||||||
|
var sign string
|
||||||
|
if sec < 0 || ns < 0 {
|
||||||
|
sign, sec, ns = "-", -1*sec, -1*ns
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generated output always contains 0, 3, 6, or 9 fractional digits,
|
||||||
|
// depending on required precision.
|
||||||
|
str := fmt.Sprintf("%s%d.%09d", sign, sec, ns)
|
||||||
|
str = strings.TrimSuffix(str, "000")
|
||||||
|
str = strings.TrimSuffix(str, "000")
|
||||||
|
str = strings.TrimSuffix(str, ".000")
|
||||||
|
return []byte(fmt.Sprintf("\"%ss\"", str)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON unmarshals b as a duration JSON string into d.
|
||||||
|
func (d *Duration) UnmarshalJSON(b []byte) error {
|
||||||
|
var s string
|
||||||
|
if err := json.Unmarshal(b, &s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !strings.HasSuffix(s, "s") {
|
||||||
|
return fmt.Errorf("malformed duration %q: missing seconds unit", s)
|
||||||
|
}
|
||||||
|
neg := false
|
||||||
|
if s[0] == '-' {
|
||||||
|
neg = true
|
||||||
|
s = s[1:]
|
||||||
|
}
|
||||||
|
ss := strings.SplitN(s[:len(s)-1], ".", 3)
|
||||||
|
if len(ss) > 2 {
|
||||||
|
return fmt.Errorf("malformed duration %q: too many decimals", s)
|
||||||
|
}
|
||||||
|
// hasDigits is set if either the whole or fractional part of the number is
|
||||||
|
// present, since both are optional but one is required.
|
||||||
|
hasDigits := false
|
||||||
|
var sec, ns int64
|
||||||
|
if len(ss[0]) > 0 {
|
||||||
|
var err error
|
||||||
|
if sec, err = strconv.ParseInt(ss[0], 10, 64); err != nil {
|
||||||
|
return fmt.Errorf("malformed duration %q: %v", s, err)
|
||||||
|
}
|
||||||
|
// Maximum seconds value per the durationpb spec.
|
||||||
|
const maxProtoSeconds = 315_576_000_000
|
||||||
|
if sec > maxProtoSeconds {
|
||||||
|
return fmt.Errorf("out of range: %q", s)
|
||||||
|
}
|
||||||
|
hasDigits = true
|
||||||
|
}
|
||||||
|
if len(ss) == 2 && len(ss[1]) > 0 {
|
||||||
|
if len(ss[1]) > 9 {
|
||||||
|
return fmt.Errorf("malformed duration %q: too many digits after decimal", s)
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
if ns, err = strconv.ParseInt(ss[1], 10, 64); err != nil {
|
||||||
|
return fmt.Errorf("malformed duration %q: %v", s, err)
|
||||||
|
}
|
||||||
|
for i := 9; i > len(ss[1]); i-- {
|
||||||
|
ns *= 10
|
||||||
|
}
|
||||||
|
hasDigits = true
|
||||||
|
}
|
||||||
|
if !hasDigits {
|
||||||
|
return fmt.Errorf("malformed duration %q: contains no numbers", s)
|
||||||
|
}
|
||||||
|
|
||||||
|
if neg {
|
||||||
|
sec *= -1
|
||||||
|
ns *= -1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Maximum/minimum seconds/nanoseconds representable by Go's time.Duration.
|
||||||
|
const maxSeconds = math.MaxInt64 / int64(time.Second)
|
||||||
|
const maxNanosAtMaxSeconds = math.MaxInt64 % int64(time.Second)
|
||||||
|
const minSeconds = math.MinInt64 / int64(time.Second)
|
||||||
|
const minNanosAtMinSeconds = math.MinInt64 % int64(time.Second)
|
||||||
|
|
||||||
|
if sec > maxSeconds || (sec == maxSeconds && ns >= maxNanosAtMaxSeconds) {
|
||||||
|
*d = Duration(math.MaxInt64)
|
||||||
|
} else if sec < minSeconds || (sec == minSeconds && ns <= minNanosAtMinSeconds) {
|
||||||
|
*d = Duration(math.MinInt64)
|
||||||
|
} else {
|
||||||
|
*d = Duration(sec*int64(time.Second) + ns)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
8
vendor/google.golang.org/grpc/internal/status/status.go
generated
vendored
8
vendor/google.golang.org/grpc/internal/status/status.go
generated
vendored
@ -49,7 +49,7 @@ func New(c codes.Code, msg string) *Status {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Newf returns New(c, fmt.Sprintf(format, a...)).
|
// Newf returns New(c, fmt.Sprintf(format, a...)).
|
||||||
func Newf(c codes.Code, format string, a ...interface{}) *Status {
|
func Newf(c codes.Code, format string, a ...any) *Status {
|
||||||
return New(c, fmt.Sprintf(format, a...))
|
return New(c, fmt.Sprintf(format, a...))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ func Err(c codes.Code, msg string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Errorf returns Error(c, fmt.Sprintf(format, a...)).
|
// Errorf returns Error(c, fmt.Sprintf(format, a...)).
|
||||||
func Errorf(c codes.Code, format string, a ...interface{}) error {
|
func Errorf(c codes.Code, format string, a ...any) error {
|
||||||
return Err(c, fmt.Sprintf(format, a...))
|
return Err(c, fmt.Sprintf(format, a...))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,11 +120,11 @@ func (s *Status) WithDetails(details ...proto.Message) (*Status, error) {
|
|||||||
|
|
||||||
// Details returns a slice of details messages attached to the status.
|
// Details returns a slice of details messages attached to the status.
|
||||||
// If a detail cannot be decoded, the error is returned in place of the detail.
|
// If a detail cannot be decoded, the error is returned in place of the detail.
|
||||||
func (s *Status) Details() []interface{} {
|
func (s *Status) Details() []any {
|
||||||
if s == nil || s.s == nil {
|
if s == nil || s.s == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
details := make([]interface{}, 0, len(s.s.Details))
|
details := make([]any, 0, len(s.s.Details))
|
||||||
for _, any := range s.s.Details {
|
for _, any := range s.s.Details {
|
||||||
detail := &ptypes.DynamicAny{}
|
detail := &ptypes.DynamicAny{}
|
||||||
if err := ptypes.UnmarshalAny(any, detail); err != nil {
|
if err := ptypes.UnmarshalAny(any, detail); err != nil {
|
||||||
|
109
vendor/google.golang.org/grpc/internal/transport/controlbuf.go
generated
vendored
109
vendor/google.golang.org/grpc/internal/transport/controlbuf.go
generated
vendored
@ -22,6 +22,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
@ -29,6 +30,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/grpclog"
|
||||||
"google.golang.org/grpc/internal/grpcutil"
|
"google.golang.org/grpc/internal/grpcutil"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
)
|
)
|
||||||
@ -38,7 +40,7 @@ var updateHeaderTblSize = func(e *hpack.Encoder, v uint32) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type itemNode struct {
|
type itemNode struct {
|
||||||
it interface{}
|
it any
|
||||||
next *itemNode
|
next *itemNode
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,7 +49,7 @@ type itemList struct {
|
|||||||
tail *itemNode
|
tail *itemNode
|
||||||
}
|
}
|
||||||
|
|
||||||
func (il *itemList) enqueue(i interface{}) {
|
func (il *itemList) enqueue(i any) {
|
||||||
n := &itemNode{it: i}
|
n := &itemNode{it: i}
|
||||||
if il.tail == nil {
|
if il.tail == nil {
|
||||||
il.head, il.tail = n, n
|
il.head, il.tail = n, n
|
||||||
@ -59,11 +61,11 @@ func (il *itemList) enqueue(i interface{}) {
|
|||||||
|
|
||||||
// peek returns the first item in the list without removing it from the
|
// peek returns the first item in the list without removing it from the
|
||||||
// list.
|
// list.
|
||||||
func (il *itemList) peek() interface{} {
|
func (il *itemList) peek() any {
|
||||||
return il.head.it
|
return il.head.it
|
||||||
}
|
}
|
||||||
|
|
||||||
func (il *itemList) dequeue() interface{} {
|
func (il *itemList) dequeue() any {
|
||||||
if il.head == nil {
|
if il.head == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -334,7 +336,7 @@ func (c *controlBuffer) put(it cbItem) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *controlBuffer) executeAndPut(f func(it interface{}) bool, it cbItem) (bool, error) {
|
func (c *controlBuffer) executeAndPut(f func(it any) bool, it cbItem) (bool, error) {
|
||||||
var wakeUp bool
|
var wakeUp bool
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
if c.err != nil {
|
if c.err != nil {
|
||||||
@ -371,7 +373,7 @@ func (c *controlBuffer) executeAndPut(f func(it interface{}) bool, it cbItem) (b
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Note argument f should never be nil.
|
// Note argument f should never be nil.
|
||||||
func (c *controlBuffer) execute(f func(it interface{}) bool, it interface{}) (bool, error) {
|
func (c *controlBuffer) execute(f func(it any) bool, it any) (bool, error) {
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
if c.err != nil {
|
if c.err != nil {
|
||||||
c.mu.Unlock()
|
c.mu.Unlock()
|
||||||
@ -385,7 +387,7 @@ func (c *controlBuffer) execute(f func(it interface{}) bool, it interface{}) (bo
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *controlBuffer) get(block bool) (interface{}, error) {
|
func (c *controlBuffer) get(block bool) (any, error) {
|
||||||
for {
|
for {
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
if c.err != nil {
|
if c.err != nil {
|
||||||
@ -486,12 +488,14 @@ type loopyWriter struct {
|
|||||||
hEnc *hpack.Encoder // HPACK encoder.
|
hEnc *hpack.Encoder // HPACK encoder.
|
||||||
bdpEst *bdpEstimator
|
bdpEst *bdpEstimator
|
||||||
draining bool
|
draining bool
|
||||||
|
conn net.Conn
|
||||||
|
logger *grpclog.PrefixLogger
|
||||||
|
|
||||||
// Side-specific handlers
|
// Side-specific handlers
|
||||||
ssGoAwayHandler func(*goAway) (bool, error)
|
ssGoAwayHandler func(*goAway) (bool, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newLoopyWriter(s side, fr *framer, cbuf *controlBuffer, bdpEst *bdpEstimator) *loopyWriter {
|
func newLoopyWriter(s side, fr *framer, cbuf *controlBuffer, bdpEst *bdpEstimator, conn net.Conn, logger *grpclog.PrefixLogger) *loopyWriter {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
l := &loopyWriter{
|
l := &loopyWriter{
|
||||||
side: s,
|
side: s,
|
||||||
@ -504,6 +508,8 @@ func newLoopyWriter(s side, fr *framer, cbuf *controlBuffer, bdpEst *bdpEstimato
|
|||||||
hBuf: &buf,
|
hBuf: &buf,
|
||||||
hEnc: hpack.NewEncoder(&buf),
|
hEnc: hpack.NewEncoder(&buf),
|
||||||
bdpEst: bdpEst,
|
bdpEst: bdpEst,
|
||||||
|
conn: conn,
|
||||||
|
logger: logger,
|
||||||
}
|
}
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
@ -521,15 +527,27 @@ const minBatchSize = 1000
|
|||||||
// 2. Stream level flow control quota available.
|
// 2. Stream level flow control quota available.
|
||||||
//
|
//
|
||||||
// In each iteration of run loop, other than processing the incoming control
|
// In each iteration of run loop, other than processing the incoming control
|
||||||
// frame, loopy calls processData, which processes one node from the activeStreams linked-list.
|
// frame, loopy calls processData, which processes one node from the
|
||||||
// This results in writing of HTTP2 frames into an underlying write buffer.
|
// activeStreams linked-list. This results in writing of HTTP2 frames into an
|
||||||
// When there's no more control frames to read from controlBuf, loopy flushes the write buffer.
|
// underlying write buffer. When there's no more control frames to read from
|
||||||
// As an optimization, to increase the batch size for each flush, loopy yields the processor, once
|
// controlBuf, loopy flushes the write buffer. As an optimization, to increase
|
||||||
// if the batch size is too low to give stream goroutines a chance to fill it up.
|
// the batch size for each flush, loopy yields the processor, once if the batch
|
||||||
|
// size is too low to give stream goroutines a chance to fill it up.
|
||||||
|
//
|
||||||
|
// Upon exiting, if the error causing the exit is not an I/O error, run()
|
||||||
|
// flushes and closes the underlying connection. Otherwise, the connection is
|
||||||
|
// left open to allow the I/O error to be encountered by the reader instead.
|
||||||
func (l *loopyWriter) run() (err error) {
|
func (l *loopyWriter) run() (err error) {
|
||||||
// Always flush the writer before exiting in case there are pending frames
|
defer func() {
|
||||||
// to be sent.
|
if l.logger.V(logLevel) {
|
||||||
defer l.framer.writer.Flush()
|
l.logger.Infof("loopyWriter exiting with error: %v", err)
|
||||||
|
}
|
||||||
|
if !isIOError(err) {
|
||||||
|
l.framer.writer.Flush()
|
||||||
|
l.conn.Close()
|
||||||
|
}
|
||||||
|
l.cbuf.finish()
|
||||||
|
}()
|
||||||
for {
|
for {
|
||||||
it, err := l.cbuf.get(true)
|
it, err := l.cbuf.get(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -581,11 +599,11 @@ func (l *loopyWriter) outgoingWindowUpdateHandler(w *outgoingWindowUpdate) error
|
|||||||
return l.framer.fr.WriteWindowUpdate(w.streamID, w.increment)
|
return l.framer.fr.WriteWindowUpdate(w.streamID, w.increment)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *loopyWriter) incomingWindowUpdateHandler(w *incomingWindowUpdate) error {
|
func (l *loopyWriter) incomingWindowUpdateHandler(w *incomingWindowUpdate) {
|
||||||
// Otherwise update the quota.
|
// Otherwise update the quota.
|
||||||
if w.streamID == 0 {
|
if w.streamID == 0 {
|
||||||
l.sendQuota += w.increment
|
l.sendQuota += w.increment
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
// Find the stream and update it.
|
// Find the stream and update it.
|
||||||
if str, ok := l.estdStreams[w.streamID]; ok {
|
if str, ok := l.estdStreams[w.streamID]; ok {
|
||||||
@ -593,10 +611,9 @@ func (l *loopyWriter) incomingWindowUpdateHandler(w *incomingWindowUpdate) error
|
|||||||
if strQuota := int(l.oiws) - str.bytesOutStanding; strQuota > 0 && str.state == waitingOnStreamQuota {
|
if strQuota := int(l.oiws) - str.bytesOutStanding; strQuota > 0 && str.state == waitingOnStreamQuota {
|
||||||
str.state = active
|
str.state = active
|
||||||
l.activeStreams.enqueue(str)
|
l.activeStreams.enqueue(str)
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *loopyWriter) outgoingSettingsHandler(s *outgoingSettings) error {
|
func (l *loopyWriter) outgoingSettingsHandler(s *outgoingSettings) error {
|
||||||
@ -604,13 +621,11 @@ func (l *loopyWriter) outgoingSettingsHandler(s *outgoingSettings) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *loopyWriter) incomingSettingsHandler(s *incomingSettings) error {
|
func (l *loopyWriter) incomingSettingsHandler(s *incomingSettings) error {
|
||||||
if err := l.applySettings(s.ss); err != nil {
|
l.applySettings(s.ss)
|
||||||
return err
|
|
||||||
}
|
|
||||||
return l.framer.fr.WriteSettingsAck()
|
return l.framer.fr.WriteSettingsAck()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *loopyWriter) registerStreamHandler(h *registerStream) error {
|
func (l *loopyWriter) registerStreamHandler(h *registerStream) {
|
||||||
str := &outStream{
|
str := &outStream{
|
||||||
id: h.streamID,
|
id: h.streamID,
|
||||||
state: empty,
|
state: empty,
|
||||||
@ -618,15 +633,14 @@ func (l *loopyWriter) registerStreamHandler(h *registerStream) error {
|
|||||||
wq: h.wq,
|
wq: h.wq,
|
||||||
}
|
}
|
||||||
l.estdStreams[h.streamID] = str
|
l.estdStreams[h.streamID] = str
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *loopyWriter) headerHandler(h *headerFrame) error {
|
func (l *loopyWriter) headerHandler(h *headerFrame) error {
|
||||||
if l.side == serverSide {
|
if l.side == serverSide {
|
||||||
str, ok := l.estdStreams[h.streamID]
|
str, ok := l.estdStreams[h.streamID]
|
||||||
if !ok {
|
if !ok {
|
||||||
if logger.V(logLevel) {
|
if l.logger.V(logLevel) {
|
||||||
logger.Warningf("transport: loopy doesn't recognize the stream: %d", h.streamID)
|
l.logger.Infof("Unrecognized streamID %d in loopyWriter", h.streamID)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -681,8 +695,8 @@ func (l *loopyWriter) writeHeader(streamID uint32, endStream bool, hf []hpack.He
|
|||||||
l.hBuf.Reset()
|
l.hBuf.Reset()
|
||||||
for _, f := range hf {
|
for _, f := range hf {
|
||||||
if err := l.hEnc.WriteField(f); err != nil {
|
if err := l.hEnc.WriteField(f); err != nil {
|
||||||
if logger.V(logLevel) {
|
if l.logger.V(logLevel) {
|
||||||
logger.Warningf("transport: loopyWriter.writeHeader encountered error while encoding headers: %v", err)
|
l.logger.Warningf("Encountered error while encoding headers: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -720,10 +734,10 @@ func (l *loopyWriter) writeHeader(streamID uint32, endStream bool, hf []hpack.He
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *loopyWriter) preprocessData(df *dataFrame) error {
|
func (l *loopyWriter) preprocessData(df *dataFrame) {
|
||||||
str, ok := l.estdStreams[df.streamID]
|
str, ok := l.estdStreams[df.streamID]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
// If we got data for a stream it means that
|
// If we got data for a stream it means that
|
||||||
// stream was originated and the headers were sent out.
|
// stream was originated and the headers were sent out.
|
||||||
@ -732,7 +746,6 @@ func (l *loopyWriter) preprocessData(df *dataFrame) error {
|
|||||||
str.state = active
|
str.state = active
|
||||||
l.activeStreams.enqueue(str)
|
l.activeStreams.enqueue(str)
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *loopyWriter) pingHandler(p *ping) error {
|
func (l *loopyWriter) pingHandler(p *ping) error {
|
||||||
@ -743,9 +756,8 @@ func (l *loopyWriter) pingHandler(p *ping) error {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *loopyWriter) outFlowControlSizeRequestHandler(o *outFlowControlSizeRequest) error {
|
func (l *loopyWriter) outFlowControlSizeRequestHandler(o *outFlowControlSizeRequest) {
|
||||||
o.resp <- l.sendQuota
|
o.resp <- l.sendQuota
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *loopyWriter) cleanupStreamHandler(c *cleanupStream) error {
|
func (l *loopyWriter) cleanupStreamHandler(c *cleanupStream) error {
|
||||||
@ -763,6 +775,7 @@ func (l *loopyWriter) cleanupStreamHandler(c *cleanupStream) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if l.draining && len(l.estdStreams) == 0 {
|
if l.draining && len(l.estdStreams) == 0 {
|
||||||
|
// Flush and close the connection; we are done with it.
|
||||||
return errors.New("finished processing active streams while in draining mode")
|
return errors.New("finished processing active streams while in draining mode")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -798,6 +811,7 @@ func (l *loopyWriter) incomingGoAwayHandler(*incomingGoAway) error {
|
|||||||
if l.side == clientSide {
|
if l.side == clientSide {
|
||||||
l.draining = true
|
l.draining = true
|
||||||
if len(l.estdStreams) == 0 {
|
if len(l.estdStreams) == 0 {
|
||||||
|
// Flush and close the connection; we are done with it.
|
||||||
return errors.New("received GOAWAY with no active streams")
|
return errors.New("received GOAWAY with no active streams")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -816,17 +830,10 @@ func (l *loopyWriter) goAwayHandler(g *goAway) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *loopyWriter) closeConnectionHandler() error {
|
func (l *loopyWriter) handle(i any) error {
|
||||||
// Exit loopyWriter entirely by returning an error here. This will lead to
|
|
||||||
// the transport closing the connection, and, ultimately, transport
|
|
||||||
// closure.
|
|
||||||
return ErrConnClosing
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *loopyWriter) handle(i interface{}) error {
|
|
||||||
switch i := i.(type) {
|
switch i := i.(type) {
|
||||||
case *incomingWindowUpdate:
|
case *incomingWindowUpdate:
|
||||||
return l.incomingWindowUpdateHandler(i)
|
l.incomingWindowUpdateHandler(i)
|
||||||
case *outgoingWindowUpdate:
|
case *outgoingWindowUpdate:
|
||||||
return l.outgoingWindowUpdateHandler(i)
|
return l.outgoingWindowUpdateHandler(i)
|
||||||
case *incomingSettings:
|
case *incomingSettings:
|
||||||
@ -836,7 +843,7 @@ func (l *loopyWriter) handle(i interface{}) error {
|
|||||||
case *headerFrame:
|
case *headerFrame:
|
||||||
return l.headerHandler(i)
|
return l.headerHandler(i)
|
||||||
case *registerStream:
|
case *registerStream:
|
||||||
return l.registerStreamHandler(i)
|
l.registerStreamHandler(i)
|
||||||
case *cleanupStream:
|
case *cleanupStream:
|
||||||
return l.cleanupStreamHandler(i)
|
return l.cleanupStreamHandler(i)
|
||||||
case *earlyAbortStream:
|
case *earlyAbortStream:
|
||||||
@ -844,21 +851,24 @@ func (l *loopyWriter) handle(i interface{}) error {
|
|||||||
case *incomingGoAway:
|
case *incomingGoAway:
|
||||||
return l.incomingGoAwayHandler(i)
|
return l.incomingGoAwayHandler(i)
|
||||||
case *dataFrame:
|
case *dataFrame:
|
||||||
return l.preprocessData(i)
|
l.preprocessData(i)
|
||||||
case *ping:
|
case *ping:
|
||||||
return l.pingHandler(i)
|
return l.pingHandler(i)
|
||||||
case *goAway:
|
case *goAway:
|
||||||
return l.goAwayHandler(i)
|
return l.goAwayHandler(i)
|
||||||
case *outFlowControlSizeRequest:
|
case *outFlowControlSizeRequest:
|
||||||
return l.outFlowControlSizeRequestHandler(i)
|
l.outFlowControlSizeRequestHandler(i)
|
||||||
case closeConnection:
|
case closeConnection:
|
||||||
return l.closeConnectionHandler()
|
// Just return a non-I/O error and run() will flush and close the
|
||||||
|
// connection.
|
||||||
|
return ErrConnClosing
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("transport: unknown control message type %T", i)
|
return fmt.Errorf("transport: unknown control message type %T", i)
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *loopyWriter) applySettings(ss []http2.Setting) error {
|
func (l *loopyWriter) applySettings(ss []http2.Setting) {
|
||||||
for _, s := range ss {
|
for _, s := range ss {
|
||||||
switch s.ID {
|
switch s.ID {
|
||||||
case http2.SettingInitialWindowSize:
|
case http2.SettingInitialWindowSize:
|
||||||
@ -877,7 +887,6 @@ func (l *loopyWriter) applySettings(ss []http2.Setting) error {
|
|||||||
updateHeaderTblSize(l.hEnc, s.Val)
|
updateHeaderTblSize(l.hEnc, s.Val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// processData removes the first stream from active streams, writes out at most 16KB
|
// processData removes the first stream from active streams, writes out at most 16KB
|
||||||
@ -911,7 +920,7 @@ func (l *loopyWriter) processData() (bool, error) {
|
|||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
if err := l.cleanupStreamHandler(trailer.cleanup); err != nil {
|
if err := l.cleanupStreamHandler(trailer.cleanup); err != nil {
|
||||||
return false, nil
|
return false, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
l.activeStreams.enqueue(str)
|
l.activeStreams.enqueue(str)
|
||||||
|
9
vendor/google.golang.org/grpc/internal/transport/handler_server.go
generated
vendored
9
vendor/google.golang.org/grpc/internal/transport/handler_server.go
generated
vendored
@ -39,6 +39,7 @@ import (
|
|||||||
"golang.org/x/net/http2"
|
"golang.org/x/net/http2"
|
||||||
"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/grpclog"
|
||||||
"google.golang.org/grpc/internal/grpcutil"
|
"google.golang.org/grpc/internal/grpcutil"
|
||||||
"google.golang.org/grpc/metadata"
|
"google.golang.org/grpc/metadata"
|
||||||
"google.golang.org/grpc/peer"
|
"google.golang.org/grpc/peer"
|
||||||
@ -83,6 +84,7 @@ func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request, stats []s
|
|||||||
contentSubtype: contentSubtype,
|
contentSubtype: contentSubtype,
|
||||||
stats: stats,
|
stats: stats,
|
||||||
}
|
}
|
||||||
|
st.logger = prefixLoggerForServerHandlerTransport(st)
|
||||||
|
|
||||||
if v := r.Header.Get("grpc-timeout"); v != "" {
|
if v := r.Header.Get("grpc-timeout"); v != "" {
|
||||||
to, err := decodeTimeout(v)
|
to, err := decodeTimeout(v)
|
||||||
@ -151,12 +153,13 @@ type serverHandlerTransport struct {
|
|||||||
contentSubtype string
|
contentSubtype string
|
||||||
|
|
||||||
stats []stats.Handler
|
stats []stats.Handler
|
||||||
|
logger *grpclog.PrefixLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ht *serverHandlerTransport) Close(err error) {
|
func (ht *serverHandlerTransport) Close(err error) {
|
||||||
ht.closeOnce.Do(func() {
|
ht.closeOnce.Do(func() {
|
||||||
if logger.V(logLevel) {
|
if ht.logger.V(logLevel) {
|
||||||
logger.Infof("Closing serverHandlerTransport: %v", err)
|
ht.logger.Infof("Closing: %v", err)
|
||||||
}
|
}
|
||||||
close(ht.closedCh)
|
close(ht.closedCh)
|
||||||
})
|
})
|
||||||
@ -450,7 +453,7 @@ func (ht *serverHandlerTransport) IncrMsgSent() {}
|
|||||||
|
|
||||||
func (ht *serverHandlerTransport) IncrMsgRecv() {}
|
func (ht *serverHandlerTransport) IncrMsgRecv() {}
|
||||||
|
|
||||||
func (ht *serverHandlerTransport) Drain() {
|
func (ht *serverHandlerTransport) Drain(debugData string) {
|
||||||
panic("Drain() is not implemented")
|
panic("Drain() is not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
87
vendor/google.golang.org/grpc/internal/transport/http2_client.go
generated
vendored
87
vendor/google.golang.org/grpc/internal/transport/http2_client.go
generated
vendored
@ -38,6 +38,7 @@ import (
|
|||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
"google.golang.org/grpc/internal/channelz"
|
"google.golang.org/grpc/internal/channelz"
|
||||||
icredentials "google.golang.org/grpc/internal/credentials"
|
icredentials "google.golang.org/grpc/internal/credentials"
|
||||||
|
"google.golang.org/grpc/internal/grpclog"
|
||||||
"google.golang.org/grpc/internal/grpcsync"
|
"google.golang.org/grpc/internal/grpcsync"
|
||||||
"google.golang.org/grpc/internal/grpcutil"
|
"google.golang.org/grpc/internal/grpcutil"
|
||||||
imetadata "google.golang.org/grpc/internal/metadata"
|
imetadata "google.golang.org/grpc/internal/metadata"
|
||||||
@ -145,6 +146,7 @@ type http2Client struct {
|
|||||||
bufferPool *bufferPool
|
bufferPool *bufferPool
|
||||||
|
|
||||||
connectionID uint64
|
connectionID uint64
|
||||||
|
logger *grpclog.PrefixLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
func dial(ctx context.Context, fn func(context.Context, string) (net.Conn, error), addr resolver.Address, useProxy bool, grpcUA string) (net.Conn, error) {
|
func dial(ctx context.Context, fn func(context.Context, string) (net.Conn, error), addr resolver.Address, useProxy bool, grpcUA string) (net.Conn, error) {
|
||||||
@ -244,7 +246,7 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts
|
|||||||
if err := connectCtx.Err(); err != nil {
|
if err := connectCtx.Err(); err != nil {
|
||||||
// connectCtx expired before exiting the function. Hard close the connection.
|
// connectCtx expired before exiting the function. Hard close the connection.
|
||||||
if logger.V(logLevel) {
|
if logger.V(logLevel) {
|
||||||
logger.Infof("newClientTransport: aborting due to connectCtx: %v", err)
|
logger.Infof("Aborting due to connect deadline expiring: %v", err)
|
||||||
}
|
}
|
||||||
conn.Close()
|
conn.Close()
|
||||||
}
|
}
|
||||||
@ -328,7 +330,7 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts
|
|||||||
readerDone: make(chan struct{}),
|
readerDone: make(chan struct{}),
|
||||||
writerDone: make(chan struct{}),
|
writerDone: make(chan struct{}),
|
||||||
goAway: make(chan struct{}),
|
goAway: make(chan struct{}),
|
||||||
framer: newFramer(conn, writeBufSize, readBufSize, maxHeaderListSize),
|
framer: newFramer(conn, writeBufSize, readBufSize, opts.SharedWriteBuffer, maxHeaderListSize),
|
||||||
fc: &trInFlow{limit: uint32(icwz)},
|
fc: &trInFlow{limit: uint32(icwz)},
|
||||||
scheme: scheme,
|
scheme: scheme,
|
||||||
activeStreams: make(map[uint32]*Stream),
|
activeStreams: make(map[uint32]*Stream),
|
||||||
@ -346,6 +348,7 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts
|
|||||||
bufferPool: newBufferPool(),
|
bufferPool: newBufferPool(),
|
||||||
onClose: onClose,
|
onClose: onClose,
|
||||||
}
|
}
|
||||||
|
t.logger = prefixLoggerForClientTransport(t)
|
||||||
// Add peer information to the http2client context.
|
// Add peer information to the http2client context.
|
||||||
t.ctx = peer.NewContext(t.ctx, t.getPeer())
|
t.ctx = peer.NewContext(t.ctx, t.getPeer())
|
||||||
|
|
||||||
@ -444,15 +447,8 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
go func() {
|
go func() {
|
||||||
t.loopy = newLoopyWriter(clientSide, t.framer, t.controlBuf, t.bdpEst)
|
t.loopy = newLoopyWriter(clientSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger)
|
||||||
err := t.loopy.run()
|
t.loopy.run()
|
||||||
if logger.V(logLevel) {
|
|
||||||
logger.Infof("transport: loopyWriter exited. Closing connection. Err: %v", err)
|
|
||||||
}
|
|
||||||
// Do not close the transport. Let reader goroutine handle it since
|
|
||||||
// there might be data in the buffers.
|
|
||||||
t.conn.Close()
|
|
||||||
t.controlBuf.finish()
|
|
||||||
close(t.writerDone)
|
close(t.writerDone)
|
||||||
}()
|
}()
|
||||||
return t, nil
|
return t, nil
|
||||||
@ -766,7 +762,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream,
|
|||||||
firstTry := true
|
firstTry := true
|
||||||
var ch chan struct{}
|
var ch chan struct{}
|
||||||
transportDrainRequired := false
|
transportDrainRequired := false
|
||||||
checkForStreamQuota := func(it interface{}) bool {
|
checkForStreamQuota := func(it any) bool {
|
||||||
if t.streamQuota <= 0 { // Can go negative if server decreases it.
|
if t.streamQuota <= 0 { // Can go negative if server decreases it.
|
||||||
if firstTry {
|
if firstTry {
|
||||||
t.waitingStreams++
|
t.waitingStreams++
|
||||||
@ -789,7 +785,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream,
|
|||||||
s.id = h.streamID
|
s.id = h.streamID
|
||||||
s.fc = &inFlow{limit: uint32(t.initialWindowSize)}
|
s.fc = &inFlow{limit: uint32(t.initialWindowSize)}
|
||||||
t.mu.Lock()
|
t.mu.Lock()
|
||||||
if t.activeStreams == nil { // Can be niled from Close().
|
if t.state == draining || t.activeStreams == nil { // Can be niled from Close().
|
||||||
t.mu.Unlock()
|
t.mu.Unlock()
|
||||||
return false // Don't create a stream if the transport is already closed.
|
return false // Don't create a stream if the transport is already closed.
|
||||||
}
|
}
|
||||||
@ -804,7 +800,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream,
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
var hdrListSizeErr error
|
var hdrListSizeErr error
|
||||||
checkForHeaderListSize := func(it interface{}) bool {
|
checkForHeaderListSize := func(it any) bool {
|
||||||
if t.maxSendHeaderListSize == nil {
|
if t.maxSendHeaderListSize == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -819,7 +815,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream,
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
success, err := t.controlBuf.executeAndPut(func(it interface{}) bool {
|
success, err := t.controlBuf.executeAndPut(func(it any) bool {
|
||||||
return checkForHeaderListSize(it) && checkForStreamQuota(it)
|
return checkForHeaderListSize(it) && checkForStreamQuota(it)
|
||||||
}, hdr)
|
}, hdr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -866,8 +862,8 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if transportDrainRequired {
|
if transportDrainRequired {
|
||||||
if logger.V(logLevel) {
|
if t.logger.V(logLevel) {
|
||||||
logger.Infof("transport: t.nextID > MaxStreamID. Draining")
|
t.logger.Infof("Draining transport: t.nextID > MaxStreamID")
|
||||||
}
|
}
|
||||||
t.GracefulClose()
|
t.GracefulClose()
|
||||||
}
|
}
|
||||||
@ -931,7 +927,7 @@ func (t *http2Client) closeStream(s *Stream, err error, rst bool, rstCode http2.
|
|||||||
rst: rst,
|
rst: rst,
|
||||||
rstCode: rstCode,
|
rstCode: rstCode,
|
||||||
}
|
}
|
||||||
addBackStreamQuota := func(interface{}) bool {
|
addBackStreamQuota := func(any) bool {
|
||||||
t.streamQuota++
|
t.streamQuota++
|
||||||
if t.streamQuota > 0 && t.waitingStreams > 0 {
|
if t.streamQuota > 0 && t.waitingStreams > 0 {
|
||||||
select {
|
select {
|
||||||
@ -959,8 +955,8 @@ func (t *http2Client) Close(err error) {
|
|||||||
t.mu.Unlock()
|
t.mu.Unlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if logger.V(logLevel) {
|
if t.logger.V(logLevel) {
|
||||||
logger.Infof("transport: closing: %v", err)
|
t.logger.Infof("Closing: %v", err)
|
||||||
}
|
}
|
||||||
// Call t.onClose ASAP to prevent the client from attempting to create new
|
// Call t.onClose ASAP to prevent the client from attempting to create new
|
||||||
// streams.
|
// streams.
|
||||||
@ -1016,8 +1012,8 @@ func (t *http2Client) GracefulClose() {
|
|||||||
t.mu.Unlock()
|
t.mu.Unlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if logger.V(logLevel) {
|
if t.logger.V(logLevel) {
|
||||||
logger.Infof("transport: GracefulClose called")
|
t.logger.Infof("GracefulClose called")
|
||||||
}
|
}
|
||||||
t.onClose(GoAwayInvalid)
|
t.onClose(GoAwayInvalid)
|
||||||
t.state = draining
|
t.state = draining
|
||||||
@ -1084,7 +1080,7 @@ func (t *http2Client) updateWindow(s *Stream, n uint32) {
|
|||||||
// for the transport and the stream based on the current bdp
|
// for the transport and the stream based on the current bdp
|
||||||
// estimation.
|
// estimation.
|
||||||
func (t *http2Client) updateFlowControl(n uint32) {
|
func (t *http2Client) updateFlowControl(n uint32) {
|
||||||
updateIWS := func(interface{}) bool {
|
updateIWS := func(any) bool {
|
||||||
t.initialWindowSize = int32(n)
|
t.initialWindowSize = int32(n)
|
||||||
t.mu.Lock()
|
t.mu.Lock()
|
||||||
for _, s := range t.activeStreams {
|
for _, s := range t.activeStreams {
|
||||||
@ -1181,8 +1177,8 @@ func (t *http2Client) handleRSTStream(f *http2.RSTStreamFrame) {
|
|||||||
}
|
}
|
||||||
statusCode, ok := http2ErrConvTab[f.ErrCode]
|
statusCode, ok := http2ErrConvTab[f.ErrCode]
|
||||||
if !ok {
|
if !ok {
|
||||||
if logger.V(logLevel) {
|
if t.logger.V(logLevel) {
|
||||||
logger.Warningf("transport: http2Client.handleRSTStream found no mapped gRPC status for the received http2 error: %v", f.ErrCode)
|
t.logger.Infof("Received a RST_STREAM frame with code %q, but found no mapped gRPC status", f.ErrCode)
|
||||||
}
|
}
|
||||||
statusCode = codes.Unknown
|
statusCode = codes.Unknown
|
||||||
}
|
}
|
||||||
@ -1237,7 +1233,7 @@ func (t *http2Client) handleSettings(f *http2.SettingsFrame, isFirst bool) {
|
|||||||
}
|
}
|
||||||
updateFuncs = append(updateFuncs, updateStreamQuota)
|
updateFuncs = append(updateFuncs, updateStreamQuota)
|
||||||
}
|
}
|
||||||
t.controlBuf.executeAndPut(func(interface{}) bool {
|
t.controlBuf.executeAndPut(func(any) bool {
|
||||||
for _, f := range updateFuncs {
|
for _, f := range updateFuncs {
|
||||||
f()
|
f()
|
||||||
}
|
}
|
||||||
@ -1264,10 +1260,12 @@ func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) {
|
|||||||
t.mu.Unlock()
|
t.mu.Unlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if f.ErrCode == http2.ErrCodeEnhanceYourCalm {
|
if f.ErrCode == http2.ErrCodeEnhanceYourCalm && string(f.DebugData()) == "too_many_pings" {
|
||||||
if logger.V(logLevel) {
|
// When a client receives a GOAWAY with error code ENHANCE_YOUR_CALM and debug
|
||||||
logger.Infof("Client received GoAway with http2.ErrCodeEnhanceYourCalm.")
|
// data equal to ASCII "too_many_pings", it should log the occurrence at a log level that is
|
||||||
}
|
// enabled by default and double the configure KEEPALIVE_TIME used for new connections
|
||||||
|
// on that channel.
|
||||||
|
logger.Errorf("Client received GoAway with error code ENHANCE_YOUR_CALM and debug data equal to ASCII \"too_many_pings\".")
|
||||||
}
|
}
|
||||||
id := f.LastStreamID
|
id := f.LastStreamID
|
||||||
if id > 0 && id%2 == 0 {
|
if id > 0 && id%2 == 0 {
|
||||||
@ -1339,7 +1337,7 @@ func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) {
|
|||||||
|
|
||||||
// setGoAwayReason sets the value of t.goAwayReason based
|
// setGoAwayReason sets the value of t.goAwayReason based
|
||||||
// on the GoAway frame received.
|
// on the GoAway frame received.
|
||||||
// It expects a lock on transport's mutext to be held by
|
// It expects a lock on transport's mutex to be held by
|
||||||
// the caller.
|
// the caller.
|
||||||
func (t *http2Client) setGoAwayReason(f *http2.GoAwayFrame) {
|
func (t *http2Client) setGoAwayReason(f *http2.GoAwayFrame) {
|
||||||
t.goAwayReason = GoAwayNoReason
|
t.goAwayReason = GoAwayNoReason
|
||||||
@ -1507,14 +1505,15 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
isHeader := false
|
// For headers, set them in s.header and close headerChan. For trailers or
|
||||||
|
// trailers-only, closeStream will set the trailers and close headerChan as
|
||||||
// If headerChan hasn't been closed yet
|
// needed.
|
||||||
|
if !endStream {
|
||||||
|
// If headerChan hasn't been closed yet (expected, given we checked it
|
||||||
|
// above, but something else could have potentially closed the whole
|
||||||
|
// stream).
|
||||||
if atomic.CompareAndSwapUint32(&s.headerChanClosed, 0, 1) {
|
if atomic.CompareAndSwapUint32(&s.headerChanClosed, 0, 1) {
|
||||||
s.headerValid = true
|
s.headerValid = true
|
||||||
if !endStream {
|
|
||||||
// HEADERS frame block carries a Response-Headers.
|
|
||||||
isHeader = true
|
|
||||||
// These values can be set without any synchronization because
|
// These values can be set without any synchronization because
|
||||||
// stream goroutine will read it only after seeing a closed
|
// stream goroutine will read it only after seeing a closed
|
||||||
// headerChan which we'll close after setting this.
|
// headerChan which we'll close after setting this.
|
||||||
@ -1522,15 +1521,12 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) {
|
|||||||
if len(mdata) > 0 {
|
if len(mdata) > 0 {
|
||||||
s.header = mdata
|
s.header = mdata
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// HEADERS frame block carries a Trailers-Only.
|
|
||||||
s.noHeaders = true
|
|
||||||
}
|
|
||||||
close(s.headerChan)
|
close(s.headerChan)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for _, sh := range t.statsHandlers {
|
for _, sh := range t.statsHandlers {
|
||||||
if isHeader {
|
if !endStream {
|
||||||
inHeader := &stats.InHeader{
|
inHeader := &stats.InHeader{
|
||||||
Client: true,
|
Client: true,
|
||||||
WireLength: int(frame.Header().Length),
|
WireLength: int(frame.Header().Length),
|
||||||
@ -1556,9 +1552,10 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) {
|
|||||||
statusGen = status.New(rawStatusCode, grpcMessage)
|
statusGen = status.New(rawStatusCode, grpcMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if client received END_STREAM from server while stream was still active, send RST_STREAM
|
// If client received END_STREAM from server while stream was still active,
|
||||||
rst := s.getState() == streamActive
|
// send RST_STREAM.
|
||||||
t.closeStream(s, io.EOF, rst, http2.ErrCodeNo, statusGen, mdata, true)
|
rstStream := s.getState() == streamActive
|
||||||
|
t.closeStream(s, io.EOF, rstStream, http2.ErrCodeNo, statusGen, mdata, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// readServerPreface reads and handles the initial settings frame from the
|
// readServerPreface reads and handles the initial settings frame from the
|
||||||
|
107
vendor/google.golang.org/grpc/internal/transport/http2_server.go
generated
vendored
107
vendor/google.golang.org/grpc/internal/transport/http2_server.go
generated
vendored
@ -35,7 +35,9 @@ import (
|
|||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
"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/grpclog"
|
||||||
"google.golang.org/grpc/internal/grpcutil"
|
"google.golang.org/grpc/internal/grpcutil"
|
||||||
|
"google.golang.org/grpc/internal/pretty"
|
||||||
"google.golang.org/grpc/internal/syscall"
|
"google.golang.org/grpc/internal/syscall"
|
||||||
|
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
@ -129,6 +131,8 @@ type http2Server struct {
|
|||||||
// This lock may not be taken if mu is already held.
|
// This lock may not be taken if mu is already held.
|
||||||
maxStreamMu sync.Mutex
|
maxStreamMu sync.Mutex
|
||||||
maxStreamID uint32 // max stream ID ever seen
|
maxStreamID uint32 // max stream ID ever seen
|
||||||
|
|
||||||
|
logger *grpclog.PrefixLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewServerTransport creates a http2 transport with conn and configuration
|
// NewServerTransport creates a http2 transport with conn and configuration
|
||||||
@ -161,21 +165,16 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport,
|
|||||||
if config.MaxHeaderListSize != nil {
|
if config.MaxHeaderListSize != nil {
|
||||||
maxHeaderListSize = *config.MaxHeaderListSize
|
maxHeaderListSize = *config.MaxHeaderListSize
|
||||||
}
|
}
|
||||||
framer := newFramer(conn, writeBufSize, readBufSize, maxHeaderListSize)
|
framer := newFramer(conn, writeBufSize, readBufSize, config.SharedWriteBuffer, maxHeaderListSize)
|
||||||
// Send initial settings as connection preface to client.
|
// Send initial settings as connection preface to client.
|
||||||
isettings := []http2.Setting{{
|
isettings := []http2.Setting{{
|
||||||
ID: http2.SettingMaxFrameSize,
|
ID: http2.SettingMaxFrameSize,
|
||||||
Val: http2MaxFrameLen,
|
Val: http2MaxFrameLen,
|
||||||
}}
|
}}
|
||||||
// TODO(zhaoq): Have a better way to signal "no limit" because 0 is
|
if config.MaxStreams != math.MaxUint32 {
|
||||||
// permitted in the HTTP2 spec.
|
|
||||||
maxStreams := config.MaxStreams
|
|
||||||
if maxStreams == 0 {
|
|
||||||
maxStreams = math.MaxUint32
|
|
||||||
} else {
|
|
||||||
isettings = append(isettings, http2.Setting{
|
isettings = append(isettings, http2.Setting{
|
||||||
ID: http2.SettingMaxConcurrentStreams,
|
ID: http2.SettingMaxConcurrentStreams,
|
||||||
Val: maxStreams,
|
Val: config.MaxStreams,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
dynamicWindow := true
|
dynamicWindow := true
|
||||||
@ -234,7 +233,7 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport,
|
|||||||
kp.Timeout = defaultServerKeepaliveTimeout
|
kp.Timeout = defaultServerKeepaliveTimeout
|
||||||
}
|
}
|
||||||
if kp.Time != infinity {
|
if kp.Time != infinity {
|
||||||
if err = syscall.SetTCPUserTimeout(conn, kp.Timeout); err != nil {
|
if err = syscall.SetTCPUserTimeout(rawConn, kp.Timeout); err != nil {
|
||||||
return nil, connectionErrorf(false, err, "transport: failed to set TCP_USER_TIMEOUT: %v", err)
|
return nil, connectionErrorf(false, err, "transport: failed to set TCP_USER_TIMEOUT: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -254,7 +253,7 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport,
|
|||||||
framer: framer,
|
framer: framer,
|
||||||
readerDone: make(chan struct{}),
|
readerDone: make(chan struct{}),
|
||||||
writerDone: make(chan struct{}),
|
writerDone: make(chan struct{}),
|
||||||
maxStreams: maxStreams,
|
maxStreams: config.MaxStreams,
|
||||||
inTapHandle: config.InTapHandle,
|
inTapHandle: config.InTapHandle,
|
||||||
fc: &trInFlow{limit: uint32(icwz)},
|
fc: &trInFlow{limit: uint32(icwz)},
|
||||||
state: reachable,
|
state: reachable,
|
||||||
@ -267,6 +266,7 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport,
|
|||||||
czData: new(channelzData),
|
czData: new(channelzData),
|
||||||
bufferPool: newBufferPool(),
|
bufferPool: newBufferPool(),
|
||||||
}
|
}
|
||||||
|
t.logger = prefixLoggerForServerTransport(t)
|
||||||
// Add peer information to the http2server context.
|
// Add peer information to the http2server context.
|
||||||
t.ctx = peer.NewContext(t.ctx, t.getPeer())
|
t.ctx = peer.NewContext(t.ctx, t.getPeer())
|
||||||
|
|
||||||
@ -331,14 +331,9 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport,
|
|||||||
t.handleSettings(sf)
|
t.handleSettings(sf)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
t.loopy = newLoopyWriter(serverSide, t.framer, t.controlBuf, t.bdpEst)
|
t.loopy = newLoopyWriter(serverSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger)
|
||||||
t.loopy.ssGoAwayHandler = t.outgoingGoAwayHandler
|
t.loopy.ssGoAwayHandler = t.outgoingGoAwayHandler
|
||||||
err := t.loopy.run()
|
t.loopy.run()
|
||||||
if logger.V(logLevel) {
|
|
||||||
logger.Infof("transport: loopyWriter exited. Closing connection. Err: %v", err)
|
|
||||||
}
|
|
||||||
t.conn.Close()
|
|
||||||
t.controlBuf.finish()
|
|
||||||
close(t.writerDone)
|
close(t.writerDone)
|
||||||
}()
|
}()
|
||||||
go t.keepalive()
|
go t.keepalive()
|
||||||
@ -383,7 +378,7 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
|
|||||||
// if false, content-type was missing or invalid
|
// if false, content-type was missing or invalid
|
||||||
isGRPC = false
|
isGRPC = false
|
||||||
contentType = ""
|
contentType = ""
|
||||||
mdata = make(map[string][]string)
|
mdata = make(metadata.MD, len(frame.Fields))
|
||||||
httpMethod string
|
httpMethod string
|
||||||
// these are set if an error is encountered while parsing the headers
|
// these are set if an error is encountered while parsing the headers
|
||||||
protocolError bool
|
protocolError bool
|
||||||
@ -404,6 +399,17 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
|
|||||||
mdata[hf.Name] = append(mdata[hf.Name], hf.Value)
|
mdata[hf.Name] = append(mdata[hf.Name], hf.Value)
|
||||||
s.contentSubtype = contentSubtype
|
s.contentSubtype = contentSubtype
|
||||||
isGRPC = true
|
isGRPC = true
|
||||||
|
|
||||||
|
case "grpc-accept-encoding":
|
||||||
|
mdata[hf.Name] = append(mdata[hf.Name], hf.Value)
|
||||||
|
if hf.Value == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
compressors := hf.Value
|
||||||
|
if s.clientAdvertisedCompressors != "" {
|
||||||
|
compressors = s.clientAdvertisedCompressors + "," + compressors
|
||||||
|
}
|
||||||
|
s.clientAdvertisedCompressors = compressors
|
||||||
case "grpc-encoding":
|
case "grpc-encoding":
|
||||||
s.recvCompress = hf.Value
|
s.recvCompress = hf.Value
|
||||||
case ":method":
|
case ":method":
|
||||||
@ -419,8 +425,8 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
|
|||||||
// "Transports must consider requests containing the Connection header
|
// "Transports must consider requests containing the Connection header
|
||||||
// as malformed." - A41
|
// as malformed." - A41
|
||||||
case "connection":
|
case "connection":
|
||||||
if logger.V(logLevel) {
|
if t.logger.V(logLevel) {
|
||||||
logger.Errorf("transport: http2Server.operateHeaders parsed a :connection header which makes a request malformed as per the HTTP/2 spec")
|
t.logger.Infof("Received a HEADERS frame with a :connection header which makes the request malformed, as per the HTTP/2 spec")
|
||||||
}
|
}
|
||||||
protocolError = true
|
protocolError = true
|
||||||
default:
|
default:
|
||||||
@ -430,7 +436,7 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
|
|||||||
v, err := decodeMetadataHeader(hf.Name, hf.Value)
|
v, err := decodeMetadataHeader(hf.Name, hf.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
headerError = status.Newf(codes.Internal, "malformed binary metadata %q in header %q: %v", hf.Value, hf.Name, err)
|
headerError = status.Newf(codes.Internal, "malformed binary metadata %q in header %q: %v", hf.Value, hf.Name, err)
|
||||||
logger.Warningf("Failed to decode metadata header (%q, %q): %v", hf.Name, hf.Value, err)
|
t.logger.Warningf("Failed to decode metadata header (%q, %q): %v", hf.Name, hf.Value, err)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
mdata[hf.Name] = append(mdata[hf.Name], v)
|
mdata[hf.Name] = append(mdata[hf.Name], v)
|
||||||
@ -444,8 +450,8 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
|
|||||||
// error, this takes precedence over a client not speaking gRPC.
|
// error, this takes precedence over a client not speaking gRPC.
|
||||||
if len(mdata[":authority"]) > 1 || len(mdata["host"]) > 1 {
|
if len(mdata[":authority"]) > 1 || len(mdata["host"]) > 1 {
|
||||||
errMsg := fmt.Sprintf("num values of :authority: %v, num values of host: %v, both must only have 1 value as per HTTP/2 spec", len(mdata[":authority"]), len(mdata["host"]))
|
errMsg := fmt.Sprintf("num values of :authority: %v, num values of host: %v, both must only have 1 value as per HTTP/2 spec", len(mdata[":authority"]), len(mdata["host"]))
|
||||||
if logger.V(logLevel) {
|
if t.logger.V(logLevel) {
|
||||||
logger.Errorf("transport: %v", errMsg)
|
t.logger.Infof("Aborting the stream early: %v", errMsg)
|
||||||
}
|
}
|
||||||
t.controlBuf.put(&earlyAbortStream{
|
t.controlBuf.put(&earlyAbortStream{
|
||||||
httpStatus: http.StatusBadRequest,
|
httpStatus: http.StatusBadRequest,
|
||||||
@ -539,9 +545,9 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
|
|||||||
}
|
}
|
||||||
if httpMethod != http.MethodPost {
|
if httpMethod != http.MethodPost {
|
||||||
t.mu.Unlock()
|
t.mu.Unlock()
|
||||||
errMsg := fmt.Sprintf("http2Server.operateHeaders parsed a :method field: %v which should be POST", httpMethod)
|
errMsg := fmt.Sprintf("Received a HEADERS frame with :method %q which should be POST", httpMethod)
|
||||||
if logger.V(logLevel) {
|
if t.logger.V(logLevel) {
|
||||||
logger.Infof("transport: %v", errMsg)
|
t.logger.Infof("Aborting the stream early: %v", errMsg)
|
||||||
}
|
}
|
||||||
t.controlBuf.put(&earlyAbortStream{
|
t.controlBuf.put(&earlyAbortStream{
|
||||||
httpStatus: 405,
|
httpStatus: 405,
|
||||||
@ -557,8 +563,8 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
|
|||||||
var err error
|
var err error
|
||||||
if s.ctx, err = t.inTapHandle(s.ctx, &tap.Info{FullMethodName: s.method}); err != nil {
|
if s.ctx, err = t.inTapHandle(s.ctx, &tap.Info{FullMethodName: s.method}); err != nil {
|
||||||
t.mu.Unlock()
|
t.mu.Unlock()
|
||||||
if logger.V(logLevel) {
|
if t.logger.V(logLevel) {
|
||||||
logger.Infof("transport: http2Server.operateHeaders got an error from InTapHandle: %v", err)
|
t.logger.Infof("Aborting the stream early due to InTapHandle failure: %v", err)
|
||||||
}
|
}
|
||||||
stat, ok := status.FromError(err)
|
stat, ok := status.FromError(err)
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -595,7 +601,7 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
|
|||||||
LocalAddr: t.localAddr,
|
LocalAddr: t.localAddr,
|
||||||
Compression: s.recvCompress,
|
Compression: s.recvCompress,
|
||||||
WireLength: int(frame.Header().Length),
|
WireLength: int(frame.Header().Length),
|
||||||
Header: metadata.MD(mdata).Copy(),
|
Header: mdata.Copy(),
|
||||||
}
|
}
|
||||||
sh.HandleRPC(s.ctx, inHeader)
|
sh.HandleRPC(s.ctx, inHeader)
|
||||||
}
|
}
|
||||||
@ -632,8 +638,8 @@ func (t *http2Server) HandleStreams(handle func(*Stream), traceCtx func(context.
|
|||||||
atomic.StoreInt64(&t.lastRead, time.Now().UnixNano())
|
atomic.StoreInt64(&t.lastRead, time.Now().UnixNano())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if se, ok := err.(http2.StreamError); ok {
|
if se, ok := err.(http2.StreamError); ok {
|
||||||
if logger.V(logLevel) {
|
if t.logger.V(logLevel) {
|
||||||
logger.Warningf("transport: http2Server.HandleStreams encountered http2.StreamError: %v", se)
|
t.logger.Warningf("Encountered http2.StreamError: %v", se)
|
||||||
}
|
}
|
||||||
t.mu.Lock()
|
t.mu.Lock()
|
||||||
s := t.activeStreams[se.StreamID]
|
s := t.activeStreams[se.StreamID]
|
||||||
@ -676,8 +682,8 @@ func (t *http2Server) HandleStreams(handle func(*Stream), traceCtx func(context.
|
|||||||
case *http2.GoAwayFrame:
|
case *http2.GoAwayFrame:
|
||||||
// TODO: Handle GoAway from the client appropriately.
|
// TODO: Handle GoAway from the client appropriately.
|
||||||
default:
|
default:
|
||||||
if logger.V(logLevel) {
|
if t.logger.V(logLevel) {
|
||||||
logger.Errorf("transport: http2Server.HandleStreams found unhandled frame type %v.", frame)
|
t.logger.Infof("Received unsupported frame type %T", frame)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -844,7 +850,7 @@ func (t *http2Server) handleSettings(f *http2.SettingsFrame) {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
t.controlBuf.executeAndPut(func(interface{}) bool {
|
t.controlBuf.executeAndPut(func(any) bool {
|
||||||
for _, f := range updateFuncs {
|
for _, f := range updateFuncs {
|
||||||
f()
|
f()
|
||||||
}
|
}
|
||||||
@ -928,7 +934,7 @@ func appendHeaderFieldsFromMD(headerFields []hpack.HeaderField, md metadata.MD)
|
|||||||
return headerFields
|
return headerFields
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *http2Server) checkForHeaderListSize(it interface{}) bool {
|
func (t *http2Server) checkForHeaderListSize(it any) bool {
|
||||||
if t.maxSendHeaderListSize == nil {
|
if t.maxSendHeaderListSize == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -936,8 +942,8 @@ func (t *http2Server) checkForHeaderListSize(it interface{}) bool {
|
|||||||
var sz int64
|
var sz int64
|
||||||
for _, f := range hdrFrame.hf {
|
for _, f := range hdrFrame.hf {
|
||||||
if sz += int64(f.Size()); sz > int64(*t.maxSendHeaderListSize) {
|
if sz += int64(f.Size()); sz > int64(*t.maxSendHeaderListSize) {
|
||||||
if logger.V(logLevel) {
|
if t.logger.V(logLevel) {
|
||||||
logger.Errorf("header list size to send violates the maximum size (%d bytes) set by client", *t.maxSendHeaderListSize)
|
t.logger.Infof("Header list size to send violates the maximum size (%d bytes) set by client", *t.maxSendHeaderListSize)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -1050,7 +1056,7 @@ func (t *http2Server) WriteStatus(s *Stream, st *status.Status) error {
|
|||||||
stBytes, err := proto.Marshal(p)
|
stBytes, err := proto.Marshal(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: return error instead, when callers are able to handle it.
|
// TODO: return error instead, when callers are able to handle it.
|
||||||
logger.Errorf("transport: failed to marshal rpc status: %v, error: %v", p, err)
|
t.logger.Errorf("Failed to marshal rpc status: %s, error: %v", pretty.ToJSON(p), err)
|
||||||
} else {
|
} else {
|
||||||
headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-status-details-bin", Value: encodeBinHeader(stBytes)})
|
headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-status-details-bin", Value: encodeBinHeader(stBytes)})
|
||||||
}
|
}
|
||||||
@ -1155,18 +1161,18 @@ func (t *http2Server) keepalive() {
|
|||||||
if val <= 0 {
|
if val <= 0 {
|
||||||
// The connection has been idle for a duration of keepalive.MaxConnectionIdle or more.
|
// The connection has been idle for a duration of keepalive.MaxConnectionIdle or more.
|
||||||
// Gracefully close the connection.
|
// Gracefully close the connection.
|
||||||
t.Drain()
|
t.Drain("max_idle")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
idleTimer.Reset(val)
|
idleTimer.Reset(val)
|
||||||
case <-ageTimer.C:
|
case <-ageTimer.C:
|
||||||
t.Drain()
|
t.Drain("max_age")
|
||||||
ageTimer.Reset(t.kp.MaxConnectionAgeGrace)
|
ageTimer.Reset(t.kp.MaxConnectionAgeGrace)
|
||||||
select {
|
select {
|
||||||
case <-ageTimer.C:
|
case <-ageTimer.C:
|
||||||
// Close the connection after grace period.
|
// Close the connection after grace period.
|
||||||
if logger.V(logLevel) {
|
if t.logger.V(logLevel) {
|
||||||
logger.Infof("transport: closing server transport due to maximum connection age.")
|
t.logger.Infof("Closing server transport due to maximum connection age")
|
||||||
}
|
}
|
||||||
t.controlBuf.put(closeConnection{})
|
t.controlBuf.put(closeConnection{})
|
||||||
case <-t.done:
|
case <-t.done:
|
||||||
@ -1217,8 +1223,8 @@ func (t *http2Server) Close(err error) {
|
|||||||
t.mu.Unlock()
|
t.mu.Unlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if logger.V(logLevel) {
|
if t.logger.V(logLevel) {
|
||||||
logger.Infof("transport: closing: %v", err)
|
t.logger.Infof("Closing: %v", err)
|
||||||
}
|
}
|
||||||
t.state = closing
|
t.state = closing
|
||||||
streams := t.activeStreams
|
streams := t.activeStreams
|
||||||
@ -1226,8 +1232,8 @@ func (t *http2Server) Close(err error) {
|
|||||||
t.mu.Unlock()
|
t.mu.Unlock()
|
||||||
t.controlBuf.finish()
|
t.controlBuf.finish()
|
||||||
close(t.done)
|
close(t.done)
|
||||||
if err := t.conn.Close(); err != nil && logger.V(logLevel) {
|
if err := t.conn.Close(); err != nil && t.logger.V(logLevel) {
|
||||||
logger.Infof("transport: error closing conn during Close: %v", err)
|
t.logger.Infof("Error closing underlying net.Conn during Close: %v", err)
|
||||||
}
|
}
|
||||||
channelz.RemoveEntry(t.channelzID)
|
channelz.RemoveEntry(t.channelzID)
|
||||||
// Cancel all active streams.
|
// Cancel all active streams.
|
||||||
@ -1307,14 +1313,14 @@ func (t *http2Server) RemoteAddr() net.Addr {
|
|||||||
return t.remoteAddr
|
return t.remoteAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *http2Server) Drain() {
|
func (t *http2Server) Drain(debugData string) {
|
||||||
t.mu.Lock()
|
t.mu.Lock()
|
||||||
defer t.mu.Unlock()
|
defer t.mu.Unlock()
|
||||||
if t.drainEvent != nil {
|
if t.drainEvent != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
t.drainEvent = grpcsync.NewEvent()
|
t.drainEvent = grpcsync.NewEvent()
|
||||||
t.controlBuf.put(&goAway{code: http2.ErrCodeNo, debugData: []byte{}, headsUp: true})
|
t.controlBuf.put(&goAway{code: http2.ErrCodeNo, debugData: []byte(debugData), headsUp: true})
|
||||||
}
|
}
|
||||||
|
|
||||||
var goAwayPing = &ping{data: [8]byte{1, 6, 1, 8, 0, 3, 3, 9}}
|
var goAwayPing = &ping{data: [8]byte{1, 6, 1, 8, 0, 3, 3, 9}}
|
||||||
@ -1344,9 +1350,6 @@ func (t *http2Server) outgoingGoAwayHandler(g *goAway) (bool, error) {
|
|||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
if retErr != nil {
|
if retErr != nil {
|
||||||
// Abruptly close the connection following the GoAway (via
|
|
||||||
// loopywriter). But flush out what's inside the buffer first.
|
|
||||||
t.framer.writer.Flush()
|
|
||||||
return false, retErr
|
return false, retErr
|
||||||
}
|
}
|
||||||
return true, nil
|
return true, nil
|
||||||
@ -1359,7 +1362,7 @@ func (t *http2Server) outgoingGoAwayHandler(g *goAway) (bool, error) {
|
|||||||
// originated before the GoAway reaches the client.
|
// originated before the GoAway reaches the client.
|
||||||
// After getting the ack or timer expiration send out another GoAway this
|
// After getting the ack or timer expiration send out another GoAway this
|
||||||
// time with an ID of the max stream server intends to process.
|
// time with an ID of the max stream server intends to process.
|
||||||
if err := t.framer.fr.WriteGoAway(math.MaxUint32, http2.ErrCodeNo, []byte{}); err != nil {
|
if err := t.framer.fr.WriteGoAway(math.MaxUint32, http2.ErrCodeNo, g.debugData); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
if err := t.framer.fr.WritePing(false, goAwayPing.data); err != nil {
|
if err := t.framer.fr.WritePing(false, goAwayPing.data); err != nil {
|
||||||
|
85
vendor/google.golang.org/grpc/internal/transport/http_util.go
generated
vendored
85
vendor/google.golang.org/grpc/internal/transport/http_util.go
generated
vendored
@ -21,6 +21,7 @@ package transport
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
@ -29,6 +30,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
@ -37,7 +39,6 @@ import (
|
|||||||
"golang.org/x/net/http2/hpack"
|
"golang.org/x/net/http2/hpack"
|
||||||
spb "google.golang.org/genproto/googleapis/rpc/status"
|
spb "google.golang.org/genproto/googleapis/rpc/status"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/grpclog"
|
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -85,7 +86,6 @@ var (
|
|||||||
// 504 Gateway timeout - UNAVAILABLE.
|
// 504 Gateway timeout - UNAVAILABLE.
|
||||||
http.StatusGatewayTimeout: codes.Unavailable,
|
http.StatusGatewayTimeout: codes.Unavailable,
|
||||||
}
|
}
|
||||||
logger = grpclog.Component("transport")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// isReservedHeader checks whether hdr belongs to HTTP2 headers
|
// isReservedHeader checks whether hdr belongs to HTTP2 headers
|
||||||
@ -310,6 +310,7 @@ func decodeGrpcMessageUnchecked(msg string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type bufWriter struct {
|
type bufWriter struct {
|
||||||
|
pool *sync.Pool
|
||||||
buf []byte
|
buf []byte
|
||||||
offset int
|
offset int
|
||||||
batchSize int
|
batchSize int
|
||||||
@ -317,12 +318,17 @@ type bufWriter struct {
|
|||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
func newBufWriter(conn net.Conn, batchSize int) *bufWriter {
|
func newBufWriter(conn net.Conn, batchSize int, pool *sync.Pool) *bufWriter {
|
||||||
return &bufWriter{
|
w := &bufWriter{
|
||||||
buf: make([]byte, batchSize*2),
|
|
||||||
batchSize: batchSize,
|
batchSize: batchSize,
|
||||||
conn: conn,
|
conn: conn,
|
||||||
|
pool: pool,
|
||||||
}
|
}
|
||||||
|
// this indicates that we should use non shared buf
|
||||||
|
if pool == nil {
|
||||||
|
w.buf = make([]byte, batchSize)
|
||||||
|
}
|
||||||
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *bufWriter) Write(b []byte) (n int, err error) {
|
func (w *bufWriter) Write(b []byte) (n int, err error) {
|
||||||
@ -330,7 +336,12 @@ func (w *bufWriter) Write(b []byte) (n int, err error) {
|
|||||||
return 0, w.err
|
return 0, w.err
|
||||||
}
|
}
|
||||||
if w.batchSize == 0 { // Buffer has been disabled.
|
if w.batchSize == 0 { // Buffer has been disabled.
|
||||||
return w.conn.Write(b)
|
n, err = w.conn.Write(b)
|
||||||
|
return n, toIOError(err)
|
||||||
|
}
|
||||||
|
if w.buf == nil {
|
||||||
|
b := w.pool.Get().(*[]byte)
|
||||||
|
w.buf = *b
|
||||||
}
|
}
|
||||||
for len(b) > 0 {
|
for len(b) > 0 {
|
||||||
nn := copy(w.buf[w.offset:], b)
|
nn := copy(w.buf[w.offset:], b)
|
||||||
@ -338,13 +349,24 @@ func (w *bufWriter) Write(b []byte) (n int, err error) {
|
|||||||
w.offset += nn
|
w.offset += nn
|
||||||
n += nn
|
n += nn
|
||||||
if w.offset >= w.batchSize {
|
if w.offset >= w.batchSize {
|
||||||
err = w.Flush()
|
err = w.flushKeepBuffer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *bufWriter) Flush() error {
|
func (w *bufWriter) Flush() error {
|
||||||
|
err := w.flushKeepBuffer()
|
||||||
|
// Only release the buffer if we are in a "shared" mode
|
||||||
|
if w.buf != nil && w.pool != nil {
|
||||||
|
b := w.buf
|
||||||
|
w.pool.Put(&b)
|
||||||
|
w.buf = nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *bufWriter) flushKeepBuffer() error {
|
||||||
if w.err != nil {
|
if w.err != nil {
|
||||||
return w.err
|
return w.err
|
||||||
}
|
}
|
||||||
@ -352,16 +374,39 @@ func (w *bufWriter) Flush() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
_, w.err = w.conn.Write(w.buf[:w.offset])
|
_, w.err = w.conn.Write(w.buf[:w.offset])
|
||||||
|
w.err = toIOError(w.err)
|
||||||
w.offset = 0
|
w.offset = 0
|
||||||
return w.err
|
return w.err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ioError struct {
|
||||||
|
error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i ioError) Unwrap() error {
|
||||||
|
return i.error
|
||||||
|
}
|
||||||
|
|
||||||
|
func isIOError(err error) bool {
|
||||||
|
return errors.As(err, &ioError{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func toIOError(err error) error {
|
||||||
|
if err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return ioError{error: err}
|
||||||
|
}
|
||||||
|
|
||||||
type framer struct {
|
type framer struct {
|
||||||
writer *bufWriter
|
writer *bufWriter
|
||||||
fr *http2.Framer
|
fr *http2.Framer
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFramer(conn net.Conn, writeBufferSize, readBufferSize int, maxHeaderListSize uint32) *framer {
|
var writeBufferPoolMap map[int]*sync.Pool = make(map[int]*sync.Pool)
|
||||||
|
var writeBufferMutex sync.Mutex
|
||||||
|
|
||||||
|
func newFramer(conn net.Conn, writeBufferSize, readBufferSize int, sharedWriteBuffer bool, maxHeaderListSize uint32) *framer {
|
||||||
if writeBufferSize < 0 {
|
if writeBufferSize < 0 {
|
||||||
writeBufferSize = 0
|
writeBufferSize = 0
|
||||||
}
|
}
|
||||||
@ -369,7 +414,11 @@ func newFramer(conn net.Conn, writeBufferSize, readBufferSize int, maxHeaderList
|
|||||||
if readBufferSize > 0 {
|
if readBufferSize > 0 {
|
||||||
r = bufio.NewReaderSize(r, readBufferSize)
|
r = bufio.NewReaderSize(r, readBufferSize)
|
||||||
}
|
}
|
||||||
w := newBufWriter(conn, writeBufferSize)
|
var pool *sync.Pool
|
||||||
|
if sharedWriteBuffer {
|
||||||
|
pool = getWriteBufferPool(writeBufferSize)
|
||||||
|
}
|
||||||
|
w := newBufWriter(conn, writeBufferSize, pool)
|
||||||
f := &framer{
|
f := &framer{
|
||||||
writer: w,
|
writer: w,
|
||||||
fr: http2.NewFramer(w, r),
|
fr: http2.NewFramer(w, r),
|
||||||
@ -383,6 +432,24 @@ func newFramer(conn net.Conn, writeBufferSize, readBufferSize int, maxHeaderList
|
|||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getWriteBufferPool(writeBufferSize int) *sync.Pool {
|
||||||
|
writeBufferMutex.Lock()
|
||||||
|
defer writeBufferMutex.Unlock()
|
||||||
|
size := writeBufferSize * 2
|
||||||
|
pool, ok := writeBufferPoolMap[size]
|
||||||
|
if ok {
|
||||||
|
return pool
|
||||||
|
}
|
||||||
|
pool = &sync.Pool{
|
||||||
|
New: func() any {
|
||||||
|
b := make([]byte, size)
|
||||||
|
return &b
|
||||||
|
},
|
||||||
|
}
|
||||||
|
writeBufferPoolMap[size] = pool
|
||||||
|
return pool
|
||||||
|
}
|
||||||
|
|
||||||
// parseDialTarget returns the network and address to pass to dialer.
|
// parseDialTarget returns the network and address to pass to dialer.
|
||||||
func parseDialTarget(target string) (string, string) {
|
func parseDialTarget(target string) (string, string) {
|
||||||
net := "tcp"
|
net := "tcp"
|
||||||
|
40
vendor/google.golang.org/grpc/internal/transport/logging.go
generated
vendored
Normal file
40
vendor/google.golang.org/grpc/internal/transport/logging.go
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2023 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package transport
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"google.golang.org/grpc/grpclog"
|
||||||
|
internalgrpclog "google.golang.org/grpc/internal/grpclog"
|
||||||
|
)
|
||||||
|
|
||||||
|
var logger = grpclog.Component("transport")
|
||||||
|
|
||||||
|
func prefixLoggerForServerTransport(p *http2Server) *internalgrpclog.PrefixLogger {
|
||||||
|
return internalgrpclog.NewPrefixLogger(logger, fmt.Sprintf("[server-transport %p] ", p))
|
||||||
|
}
|
||||||
|
|
||||||
|
func prefixLoggerForServerHandlerTransport(p *serverHandlerTransport) *internalgrpclog.PrefixLogger {
|
||||||
|
return internalgrpclog.NewPrefixLogger(logger, fmt.Sprintf("[server-handler-transport %p] ", p))
|
||||||
|
}
|
||||||
|
|
||||||
|
func prefixLoggerForClientTransport(p *http2Client) *internalgrpclog.PrefixLogger {
|
||||||
|
return internalgrpclog.NewPrefixLogger(logger, fmt.Sprintf("[client-transport %p] ", p))
|
||||||
|
}
|
42
vendor/google.golang.org/grpc/internal/transport/transport.go
generated
vendored
42
vendor/google.golang.org/grpc/internal/transport/transport.go
generated
vendored
@ -43,10 +43,6 @@ import (
|
|||||||
"google.golang.org/grpc/tap"
|
"google.golang.org/grpc/tap"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrNoHeaders is used as a signal that a trailers only response was received,
|
|
||||||
// and is not a real error.
|
|
||||||
var ErrNoHeaders = errors.New("stream has no headers")
|
|
||||||
|
|
||||||
const logLevel = 2
|
const logLevel = 2
|
||||||
|
|
||||||
type bufferPool struct {
|
type bufferPool struct {
|
||||||
@ -56,7 +52,7 @@ type bufferPool struct {
|
|||||||
func newBufferPool() *bufferPool {
|
func newBufferPool() *bufferPool {
|
||||||
return &bufferPool{
|
return &bufferPool{
|
||||||
pool: sync.Pool{
|
pool: sync.Pool{
|
||||||
New: func() interface{} {
|
New: func() any {
|
||||||
return new(bytes.Buffer)
|
return new(bytes.Buffer)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -257,6 +253,9 @@ type Stream struct {
|
|||||||
fc *inFlow
|
fc *inFlow
|
||||||
wq *writeQuota
|
wq *writeQuota
|
||||||
|
|
||||||
|
// Holds compressor names passed in grpc-accept-encoding metadata from the
|
||||||
|
// client. This is empty for the client side stream.
|
||||||
|
clientAdvertisedCompressors string
|
||||||
// Callback to state application's intentions to read data. This
|
// Callback to state application's intentions to read data. This
|
||||||
// is used to adjust flow control, if needed.
|
// is used to adjust flow control, if needed.
|
||||||
requestRead func(int)
|
requestRead func(int)
|
||||||
@ -345,8 +344,24 @@ func (s *Stream) RecvCompress() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetSendCompress sets the compression algorithm to the stream.
|
// SetSendCompress sets the compression algorithm to the stream.
|
||||||
func (s *Stream) SetSendCompress(str string) {
|
func (s *Stream) SetSendCompress(name string) error {
|
||||||
s.sendCompress = str
|
if s.isHeaderSent() || s.getState() == streamDone {
|
||||||
|
return errors.New("transport: set send compressor called after headers sent or stream done")
|
||||||
|
}
|
||||||
|
|
||||||
|
s.sendCompress = name
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendCompress returns the send compressor name.
|
||||||
|
func (s *Stream) SendCompress() string {
|
||||||
|
return s.sendCompress
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClientAdvertisedCompressors returns the compressor names advertised by the
|
||||||
|
// client via grpc-accept-encoding header.
|
||||||
|
func (s *Stream) ClientAdvertisedCompressors() string {
|
||||||
|
return s.clientAdvertisedCompressors
|
||||||
}
|
}
|
||||||
|
|
||||||
// Done returns a channel which is closed when it receives the final status
|
// Done returns a channel which is closed when it receives the final status
|
||||||
@ -371,14 +386,10 @@ func (s *Stream) Header() (metadata.MD, error) {
|
|||||||
}
|
}
|
||||||
s.waitOnHeader()
|
s.waitOnHeader()
|
||||||
|
|
||||||
if !s.headerValid {
|
if !s.headerValid || s.noHeaders {
|
||||||
return nil, s.status.Err()
|
return nil, s.status.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.noHeaders {
|
|
||||||
return nil, ErrNoHeaders
|
|
||||||
}
|
|
||||||
|
|
||||||
return s.header.Copy(), nil
|
return s.header.Copy(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -540,6 +551,7 @@ type ServerConfig struct {
|
|||||||
InitialConnWindowSize int32
|
InitialConnWindowSize int32
|
||||||
WriteBufferSize int
|
WriteBufferSize int
|
||||||
ReadBufferSize int
|
ReadBufferSize int
|
||||||
|
SharedWriteBuffer bool
|
||||||
ChannelzParentID *channelz.Identifier
|
ChannelzParentID *channelz.Identifier
|
||||||
MaxHeaderListSize *uint32
|
MaxHeaderListSize *uint32
|
||||||
HeaderTableSize *uint32
|
HeaderTableSize *uint32
|
||||||
@ -573,6 +585,8 @@ type ConnectOptions struct {
|
|||||||
WriteBufferSize int
|
WriteBufferSize int
|
||||||
// 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
|
||||||
|
// SharedWriteBuffer indicates whether connections should reuse write buffer
|
||||||
|
SharedWriteBuffer bool
|
||||||
// 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 *channelz.Identifier
|
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.
|
||||||
@ -707,7 +721,7 @@ type ServerTransport interface {
|
|||||||
RemoteAddr() net.Addr
|
RemoteAddr() net.Addr
|
||||||
|
|
||||||
// Drain notifies the client this ServerTransport stops accepting new RPCs.
|
// Drain notifies the client this ServerTransport stops accepting new RPCs.
|
||||||
Drain()
|
Drain(debugData string)
|
||||||
|
|
||||||
// IncrMsgSent increments the number of message sent through this transport.
|
// IncrMsgSent increments the number of message sent through this transport.
|
||||||
IncrMsgSent()
|
IncrMsgSent()
|
||||||
@ -717,7 +731,7 @@ type ServerTransport interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// connectionErrorf creates an ConnectionError with the specified error description.
|
// connectionErrorf creates an ConnectionError with the specified error description.
|
||||||
func connectionErrorf(temp bool, e error, format string, a ...interface{}) ConnectionError {
|
func connectionErrorf(temp bool, e error, format string, a ...any) ConnectionError {
|
||||||
return ConnectionError{
|
return ConnectionError{
|
||||||
Desc: fmt.Sprintf(format, a...),
|
Desc: fmt.Sprintf(format, a...),
|
||||||
temp: temp,
|
temp: temp,
|
||||||
|
13
vendor/google.golang.org/grpc/metadata/metadata.go
generated
vendored
13
vendor/google.golang.org/grpc/metadata/metadata.go
generated
vendored
@ -91,7 +91,11 @@ func (md MD) Len() int {
|
|||||||
|
|
||||||
// Copy returns a copy of md.
|
// Copy returns a copy of md.
|
||||||
func (md MD) Copy() MD {
|
func (md MD) Copy() MD {
|
||||||
return Join(md)
|
out := make(MD, len(md))
|
||||||
|
for k, v := range md {
|
||||||
|
out[k] = copyOf(v)
|
||||||
|
}
|
||||||
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get obtains the values for a given key.
|
// Get obtains the values for a given key.
|
||||||
@ -171,8 +175,11 @@ func AppendToOutgoingContext(ctx context.Context, kv ...string) context.Context
|
|||||||
md, _ := ctx.Value(mdOutgoingKey{}).(rawMD)
|
md, _ := ctx.Value(mdOutgoingKey{}).(rawMD)
|
||||||
added := make([][]string, len(md.added)+1)
|
added := make([][]string, len(md.added)+1)
|
||||||
copy(added, md.added)
|
copy(added, md.added)
|
||||||
added[len(added)-1] = make([]string, len(kv))
|
kvCopy := make([]string, 0, len(kv))
|
||||||
copy(added[len(added)-1], kv)
|
for i := 0; i < len(kv); i += 2 {
|
||||||
|
kvCopy = append(kvCopy, strings.ToLower(kv[i]), kv[i+1])
|
||||||
|
}
|
||||||
|
added[len(added)-1] = kvCopy
|
||||||
return context.WithValue(ctx, mdOutgoingKey{}, rawMD{md: md.md, added: added})
|
return context.WithValue(ctx, mdOutgoingKey{}, rawMD{md: md.md, added: added})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
62
vendor/google.golang.org/grpc/picker_wrapper.go
generated
vendored
62
vendor/google.golang.org/grpc/picker_wrapper.go
generated
vendored
@ -28,6 +28,7 @@ import (
|
|||||||
"google.golang.org/grpc/internal/channelz"
|
"google.golang.org/grpc/internal/channelz"
|
||||||
istatus "google.golang.org/grpc/internal/status"
|
istatus "google.golang.org/grpc/internal/status"
|
||||||
"google.golang.org/grpc/internal/transport"
|
"google.golang.org/grpc/internal/transport"
|
||||||
|
"google.golang.org/grpc/stats"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -36,18 +37,27 @@ import (
|
|||||||
type pickerWrapper struct {
|
type pickerWrapper struct {
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
done bool
|
done bool
|
||||||
|
idle bool
|
||||||
blockingCh chan struct{}
|
blockingCh chan struct{}
|
||||||
picker balancer.Picker
|
picker balancer.Picker
|
||||||
|
statsHandlers []stats.Handler // to record blocking picker calls
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPickerWrapper() *pickerWrapper {
|
func newPickerWrapper(statsHandlers []stats.Handler) *pickerWrapper {
|
||||||
return &pickerWrapper{blockingCh: make(chan struct{})}
|
return &pickerWrapper{
|
||||||
|
blockingCh: make(chan struct{}),
|
||||||
|
statsHandlers: statsHandlers,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// updatePicker is called by UpdateBalancerState. It unblocks all blocked pick.
|
// updatePicker is called by UpdateBalancerState. It unblocks all blocked pick.
|
||||||
func (pw *pickerWrapper) updatePicker(p balancer.Picker) {
|
func (pw *pickerWrapper) updatePicker(p balancer.Picker) {
|
||||||
pw.mu.Lock()
|
pw.mu.Lock()
|
||||||
if pw.done {
|
if pw.done || pw.idle {
|
||||||
|
// There is a small window where a picker update from the LB policy can
|
||||||
|
// race with the channel going to idle mode. If the picker is idle here,
|
||||||
|
// it is because the channel asked it to do so, and therefore it is sage
|
||||||
|
// to ignore the update from the LB policy.
|
||||||
pw.mu.Unlock()
|
pw.mu.Unlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -63,10 +73,8 @@ func (pw *pickerWrapper) updatePicker(p balancer.Picker) {
|
|||||||
// - wraps the done function in the passed in result to increment the calls
|
// - wraps the done function in the passed in result to increment the calls
|
||||||
// failed or calls succeeded channelz counter before invoking the actual
|
// failed or calls succeeded channelz counter before invoking the actual
|
||||||
// done function.
|
// done function.
|
||||||
func doneChannelzWrapper(acw *acBalancerWrapper, result *balancer.PickResult) {
|
func doneChannelzWrapper(acbw *acBalancerWrapper, result *balancer.PickResult) {
|
||||||
acw.mu.Lock()
|
ac := acbw.ac
|
||||||
ac := acw.ac
|
|
||||||
acw.mu.Unlock()
|
|
||||||
ac.incrCallsStarted()
|
ac.incrCallsStarted()
|
||||||
done := result.Done
|
done := result.Done
|
||||||
result.Done = func(b balancer.DoneInfo) {
|
result.Done = func(b balancer.DoneInfo) {
|
||||||
@ -92,6 +100,7 @@ func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer.
|
|||||||
var ch chan struct{}
|
var ch chan struct{}
|
||||||
|
|
||||||
var lastPickErr error
|
var lastPickErr error
|
||||||
|
|
||||||
for {
|
for {
|
||||||
pw.mu.Lock()
|
pw.mu.Lock()
|
||||||
if pw.done {
|
if pw.done {
|
||||||
@ -126,6 +135,20 @@ func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer.
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the channel is set, it means that the pick call had to wait for a
|
||||||
|
// new picker at some point. Either it's the first iteration and this
|
||||||
|
// function received the first picker, or a picker errored with
|
||||||
|
// ErrNoSubConnAvailable or errored with failfast set to false, which
|
||||||
|
// will trigger a continue to the next iteration. In the first case this
|
||||||
|
// conditional will hit if this call had to block (the channel is set).
|
||||||
|
// In the second case, the only way it will get to this conditional is
|
||||||
|
// if there is a new picker.
|
||||||
|
if ch != nil {
|
||||||
|
for _, sh := range pw.statsHandlers {
|
||||||
|
sh.HandleRPC(ctx, &stats.PickerUpdated{})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ch = pw.blockingCh
|
ch = pw.blockingCh
|
||||||
p := pw.picker
|
p := pw.picker
|
||||||
pw.mu.Unlock()
|
pw.mu.Unlock()
|
||||||
@ -152,14 +175,14 @@ func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer.
|
|||||||
return nil, balancer.PickResult{}, status.Error(codes.Unavailable, err.Error())
|
return nil, balancer.PickResult{}, status.Error(codes.Unavailable, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
acw, ok := pickResult.SubConn.(*acBalancerWrapper)
|
acbw, ok := pickResult.SubConn.(*acBalancerWrapper)
|
||||||
if !ok {
|
if !ok {
|
||||||
logger.Errorf("subconn returned from pick is type %T, not *acBalancerWrapper", pickResult.SubConn)
|
logger.Errorf("subconn returned from pick is type %T, not *acBalancerWrapper", pickResult.SubConn)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if t := acw.getAddrConn().getReadyTransport(); t != nil {
|
if t := acbw.ac.getReadyTransport(); t != nil {
|
||||||
if channelz.IsOn() {
|
if channelz.IsOn() {
|
||||||
doneChannelzWrapper(acw, &pickResult)
|
doneChannelzWrapper(acbw, &pickResult)
|
||||||
return t, pickResult, nil
|
return t, pickResult, nil
|
||||||
}
|
}
|
||||||
return t, pickResult, nil
|
return t, pickResult, nil
|
||||||
@ -187,6 +210,25 @@ func (pw *pickerWrapper) close() {
|
|||||||
close(pw.blockingCh)
|
close(pw.blockingCh)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pw *pickerWrapper) enterIdleMode() {
|
||||||
|
pw.mu.Lock()
|
||||||
|
defer pw.mu.Unlock()
|
||||||
|
if pw.done {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pw.idle = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pw *pickerWrapper) exitIdleMode() {
|
||||||
|
pw.mu.Lock()
|
||||||
|
defer pw.mu.Unlock()
|
||||||
|
if pw.done {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pw.blockingCh = make(chan struct{})
|
||||||
|
pw.idle = false
|
||||||
|
}
|
||||||
|
|
||||||
// dropError is a wrapper error that indicates the LB policy wishes to drop the
|
// dropError is a wrapper error that indicates the LB policy wishes to drop the
|
||||||
// RPC and not retry it.
|
// RPC and not retry it.
|
||||||
type dropError struct {
|
type dropError struct {
|
||||||
|
114
vendor/google.golang.org/grpc/pickfirst.go
generated
vendored
114
vendor/google.golang.org/grpc/pickfirst.go
generated
vendored
@ -19,15 +19,25 @@
|
|||||||
package grpc
|
package grpc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"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/envconfig"
|
||||||
|
internalgrpclog "google.golang.org/grpc/internal/grpclog"
|
||||||
|
"google.golang.org/grpc/internal/grpcrand"
|
||||||
|
"google.golang.org/grpc/internal/pretty"
|
||||||
|
"google.golang.org/grpc/resolver"
|
||||||
|
"google.golang.org/grpc/serviceconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
// PickFirstBalancerName is the name of the pick_first balancer.
|
// PickFirstBalancerName is the name of the pick_first balancer.
|
||||||
const PickFirstBalancerName = "pick_first"
|
PickFirstBalancerName = "pick_first"
|
||||||
|
logPrefix = "[pick-first-lb %p] "
|
||||||
|
)
|
||||||
|
|
||||||
func newPickfirstBuilder() balancer.Builder {
|
func newPickfirstBuilder() balancer.Builder {
|
||||||
return &pickfirstBuilder{}
|
return &pickfirstBuilder{}
|
||||||
@ -36,22 +46,55 @@ func newPickfirstBuilder() balancer.Builder {
|
|||||||
type pickfirstBuilder struct{}
|
type pickfirstBuilder struct{}
|
||||||
|
|
||||||
func (*pickfirstBuilder) Build(cc balancer.ClientConn, opt balancer.BuildOptions) balancer.Balancer {
|
func (*pickfirstBuilder) Build(cc balancer.ClientConn, opt balancer.BuildOptions) balancer.Balancer {
|
||||||
return &pickfirstBalancer{cc: cc}
|
b := &pickfirstBalancer{cc: cc}
|
||||||
|
b.logger = internalgrpclog.NewPrefixLogger(logger, fmt.Sprintf(logPrefix, b))
|
||||||
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*pickfirstBuilder) Name() string {
|
func (*pickfirstBuilder) Name() string {
|
||||||
return PickFirstBalancerName
|
return PickFirstBalancerName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type pfConfig struct {
|
||||||
|
serviceconfig.LoadBalancingConfig `json:"-"`
|
||||||
|
|
||||||
|
// If set to true, instructs the LB policy to shuffle the order of the list
|
||||||
|
// of addresses received from the name resolver before attempting to
|
||||||
|
// connect to them.
|
||||||
|
ShuffleAddressList bool `json:"shuffleAddressList"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*pickfirstBuilder) ParseConfig(js json.RawMessage) (serviceconfig.LoadBalancingConfig, error) {
|
||||||
|
if !envconfig.PickFirstLBConfig {
|
||||||
|
// Prior to supporting loadbalancing configuration, the pick_first LB
|
||||||
|
// policy did not implement the balancer.ConfigParser interface. This
|
||||||
|
// meant that if a non-empty configuration was passed to it, the service
|
||||||
|
// config unmarshaling code would throw a warning log, but would
|
||||||
|
// continue using the pick_first LB policy. The code below ensures the
|
||||||
|
// same behavior is retained if the env var is not set.
|
||||||
|
if string(js) != "{}" {
|
||||||
|
logger.Warningf("Ignoring non-empty balancer configuration %q for the pick_first LB policy", string(js))
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var cfg pfConfig
|
||||||
|
if err := json.Unmarshal(js, &cfg); err != nil {
|
||||||
|
return nil, fmt.Errorf("pickfirst: unable to unmarshal LB policy config: %s, error: %v", string(js), err)
|
||||||
|
}
|
||||||
|
return cfg, nil
|
||||||
|
}
|
||||||
|
|
||||||
type pickfirstBalancer struct {
|
type pickfirstBalancer struct {
|
||||||
|
logger *internalgrpclog.PrefixLogger
|
||||||
state connectivity.State
|
state connectivity.State
|
||||||
cc balancer.ClientConn
|
cc balancer.ClientConn
|
||||||
subConn balancer.SubConn
|
subConn balancer.SubConn
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *pickfirstBalancer) ResolverError(err error) {
|
func (b *pickfirstBalancer) ResolverError(err error) {
|
||||||
if logger.V(2) {
|
if b.logger.V(2) {
|
||||||
logger.Infof("pickfirstBalancer: ResolverError called with error: %v", err)
|
b.logger.Infof("Received error from the name resolver: %v", err)
|
||||||
}
|
}
|
||||||
if b.subConn == nil {
|
if b.subConn == nil {
|
||||||
b.state = connectivity.TransientFailure
|
b.state = connectivity.TransientFailure
|
||||||
@ -69,28 +112,49 @@ func (b *pickfirstBalancer) ResolverError(err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState) error {
|
func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState) error {
|
||||||
if len(state.ResolverState.Addresses) == 0 {
|
addrs := state.ResolverState.Addresses
|
||||||
|
if len(addrs) == 0 {
|
||||||
// The resolver reported an empty address list. Treat it like an error by
|
// The resolver reported an empty address list. Treat it like an error by
|
||||||
// calling b.ResolverError.
|
// calling b.ResolverError.
|
||||||
if b.subConn != nil {
|
if b.subConn != nil {
|
||||||
// Remove the old subConn. All addresses were removed, so it is no longer
|
// Shut down the old subConn. All addresses were removed, so it is
|
||||||
// valid.
|
// no longer valid.
|
||||||
b.cc.RemoveSubConn(b.subConn)
|
b.subConn.Shutdown()
|
||||||
b.subConn = nil
|
b.subConn = nil
|
||||||
}
|
}
|
||||||
b.ResolverError(errors.New("produced zero addresses"))
|
b.ResolverError(errors.New("produced zero addresses"))
|
||||||
return balancer.ErrBadResolverState
|
return balancer.ErrBadResolverState
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We don't have to guard this block with the env var because ParseConfig
|
||||||
|
// already does so.
|
||||||
|
cfg, ok := state.BalancerConfig.(pfConfig)
|
||||||
|
if state.BalancerConfig != nil && !ok {
|
||||||
|
return fmt.Errorf("pickfirst: received illegal BalancerConfig (type %T): %v", state.BalancerConfig, state.BalancerConfig)
|
||||||
|
}
|
||||||
|
if cfg.ShuffleAddressList {
|
||||||
|
addrs = append([]resolver.Address{}, addrs...)
|
||||||
|
grpcrand.Shuffle(len(addrs), func(i, j int) { addrs[i], addrs[j] = addrs[j], addrs[i] })
|
||||||
|
}
|
||||||
|
|
||||||
|
if b.logger.V(2) {
|
||||||
|
b.logger.Infof("Received new config %s, resolver state %s", pretty.ToJSON(cfg), pretty.ToJSON(state.ResolverState))
|
||||||
|
}
|
||||||
|
|
||||||
if b.subConn != nil {
|
if b.subConn != nil {
|
||||||
b.cc.UpdateAddresses(b.subConn, state.ResolverState.Addresses)
|
b.cc.UpdateAddresses(b.subConn, addrs)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
subConn, err := b.cc.NewSubConn(state.ResolverState.Addresses, balancer.NewSubConnOptions{})
|
var subConn balancer.SubConn
|
||||||
|
subConn, err := b.cc.NewSubConn(addrs, balancer.NewSubConnOptions{
|
||||||
|
StateListener: func(state balancer.SubConnState) {
|
||||||
|
b.updateSubConnState(subConn, state)
|
||||||
|
},
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if logger.V(2) {
|
if b.logger.V(2) {
|
||||||
logger.Errorf("pickfirstBalancer: failed to NewSubConn: %v", err)
|
b.logger.Infof("Failed to create new SubConn: %v", err)
|
||||||
}
|
}
|
||||||
b.state = connectivity.TransientFailure
|
b.state = connectivity.TransientFailure
|
||||||
b.cc.UpdateState(balancer.State{
|
b.cc.UpdateState(balancer.State{
|
||||||
@ -109,17 +173,22 @@ func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateSubConnState is unused as a StateListener is always registered when
|
||||||
|
// creating SubConns.
|
||||||
func (b *pickfirstBalancer) UpdateSubConnState(subConn balancer.SubConn, state balancer.SubConnState) {
|
func (b *pickfirstBalancer) UpdateSubConnState(subConn balancer.SubConn, state balancer.SubConnState) {
|
||||||
if logger.V(2) {
|
b.logger.Errorf("UpdateSubConnState(%v, %+v) called unexpectedly", subConn, state)
|
||||||
logger.Infof("pickfirstBalancer: UpdateSubConnState: %p, %v", subConn, state)
|
}
|
||||||
|
|
||||||
|
func (b *pickfirstBalancer) updateSubConnState(subConn balancer.SubConn, state balancer.SubConnState) {
|
||||||
|
if b.logger.V(2) {
|
||||||
|
b.logger.Infof("Received SubConn state update: %p, %+v", subConn, state)
|
||||||
}
|
}
|
||||||
if b.subConn != subConn {
|
if b.subConn != subConn {
|
||||||
if logger.V(2) {
|
if b.logger.V(2) {
|
||||||
logger.Infof("pickfirstBalancer: ignored state change because subConn is not recognized")
|
b.logger.Infof("Ignored state change because subConn is not recognized")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
b.state = state.ConnectivityState
|
|
||||||
if state.ConnectivityState == connectivity.Shutdown {
|
if state.ConnectivityState == connectivity.Shutdown {
|
||||||
b.subConn = nil
|
b.subConn = nil
|
||||||
return
|
return
|
||||||
@ -132,11 +201,21 @@ func (b *pickfirstBalancer) UpdateSubConnState(subConn balancer.SubConn, state b
|
|||||||
Picker: &picker{result: balancer.PickResult{SubConn: subConn}},
|
Picker: &picker{result: balancer.PickResult{SubConn: subConn}},
|
||||||
})
|
})
|
||||||
case connectivity.Connecting:
|
case connectivity.Connecting:
|
||||||
|
if b.state == connectivity.TransientFailure {
|
||||||
|
// We stay in TransientFailure until we are Ready. See A62.
|
||||||
|
return
|
||||||
|
}
|
||||||
b.cc.UpdateState(balancer.State{
|
b.cc.UpdateState(balancer.State{
|
||||||
ConnectivityState: state.ConnectivityState,
|
ConnectivityState: state.ConnectivityState,
|
||||||
Picker: &picker{err: balancer.ErrNoSubConnAvailable},
|
Picker: &picker{err: balancer.ErrNoSubConnAvailable},
|
||||||
})
|
})
|
||||||
case connectivity.Idle:
|
case connectivity.Idle:
|
||||||
|
if b.state == connectivity.TransientFailure {
|
||||||
|
// We stay in TransientFailure until we are Ready. Also kick the
|
||||||
|
// subConn out of Idle into Connecting. See A62.
|
||||||
|
b.subConn.Connect()
|
||||||
|
return
|
||||||
|
}
|
||||||
b.cc.UpdateState(balancer.State{
|
b.cc.UpdateState(balancer.State{
|
||||||
ConnectivityState: state.ConnectivityState,
|
ConnectivityState: state.ConnectivityState,
|
||||||
Picker: &idlePicker{subConn: subConn},
|
Picker: &idlePicker{subConn: subConn},
|
||||||
@ -147,6 +226,7 @@ func (b *pickfirstBalancer) UpdateSubConnState(subConn balancer.SubConn, state b
|
|||||||
Picker: &picker{err: state.ConnectionError},
|
Picker: &picker{err: state.ConnectionError},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
b.state = state.ConnectivityState
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *pickfirstBalancer) Close() {
|
func (b *pickfirstBalancer) Close() {
|
||||||
|
2
vendor/google.golang.org/grpc/preloader.go
generated
vendored
2
vendor/google.golang.org/grpc/preloader.go
generated
vendored
@ -37,7 +37,7 @@ type PreparedMsg struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Encode marshalls and compresses the message using the codec and compressor for the stream.
|
// Encode marshalls and compresses the message using the codec and compressor for the stream.
|
||||||
func (p *PreparedMsg) Encode(s Stream, msg interface{}) error {
|
func (p *PreparedMsg) Encode(s Stream, msg any) error {
|
||||||
ctx := s.Context()
|
ctx := s.Context()
|
||||||
rpcInfo, ok := rpcInfoFromContext(ctx)
|
rpcInfo, ok := rpcInfoFromContext(ctx)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
10
vendor/google.golang.org/grpc/resolver/map.go
generated
vendored
10
vendor/google.golang.org/grpc/resolver/map.go
generated
vendored
@ -20,7 +20,7 @@ package resolver
|
|||||||
|
|
||||||
type addressMapEntry struct {
|
type addressMapEntry struct {
|
||||||
addr Address
|
addr Address
|
||||||
value interface{}
|
value any
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddressMap is a map of addresses to arbitrary values taking into account
|
// AddressMap is a map of addresses to arbitrary values taking into account
|
||||||
@ -69,7 +69,7 @@ func (l addressMapEntryList) find(addr Address) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get returns the value for the address in the map, if present.
|
// Get returns the value for the address in the map, if present.
|
||||||
func (a *AddressMap) Get(addr Address) (value interface{}, ok bool) {
|
func (a *AddressMap) Get(addr Address) (value any, ok bool) {
|
||||||
addrKey := toMapKey(&addr)
|
addrKey := toMapKey(&addr)
|
||||||
entryList := a.m[addrKey]
|
entryList := a.m[addrKey]
|
||||||
if entry := entryList.find(addr); entry != -1 {
|
if entry := entryList.find(addr); entry != -1 {
|
||||||
@ -79,7 +79,7 @@ func (a *AddressMap) Get(addr Address) (value interface{}, ok bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set updates or adds the value to the address in the map.
|
// Set updates or adds the value to the address in the map.
|
||||||
func (a *AddressMap) Set(addr Address, value interface{}) {
|
func (a *AddressMap) Set(addr Address, value any) {
|
||||||
addrKey := toMapKey(&addr)
|
addrKey := toMapKey(&addr)
|
||||||
entryList := a.m[addrKey]
|
entryList := a.m[addrKey]
|
||||||
if entry := entryList.find(addr); entry != -1 {
|
if entry := entryList.find(addr); entry != -1 {
|
||||||
@ -127,8 +127,8 @@ func (a *AddressMap) Keys() []Address {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Values returns a slice of all current map values.
|
// Values returns a slice of all current map values.
|
||||||
func (a *AddressMap) Values() []interface{} {
|
func (a *AddressMap) Values() []any {
|
||||||
ret := make([]interface{}, 0, a.Len())
|
ret := make([]any, 0, a.Len())
|
||||||
for _, entryList := range a.m {
|
for _, entryList := range a.m {
|
||||||
for _, entry := range entryList {
|
for _, entry := range entryList {
|
||||||
ret = append(ret, entry.value)
|
ret = append(ret, entry.value)
|
||||||
|
120
vendor/google.golang.org/grpc/resolver/resolver.go
generated
vendored
120
vendor/google.golang.org/grpc/resolver/resolver.go
generated
vendored
@ -22,13 +22,13 @@ package resolver
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"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"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -41,8 +41,9 @@ var (
|
|||||||
|
|
||||||
// TODO(bar) install dns resolver in init(){}.
|
// TODO(bar) install dns resolver in init(){}.
|
||||||
|
|
||||||
// Register registers the resolver builder to the resolver map. b.Scheme will be
|
// Register registers the resolver builder to the resolver map. b.Scheme will
|
||||||
// used as the scheme registered with this builder.
|
// be used as the scheme registered with this builder. The registry is case
|
||||||
|
// sensitive, and schemes should not contain any uppercase characters.
|
||||||
//
|
//
|
||||||
// NOTE: this function must only be called during initialization time (i.e. in
|
// NOTE: this function must only be called during initialization time (i.e. in
|
||||||
// an init() function), and is not thread-safe. If multiple Resolvers are
|
// an init() function), and is not thread-safe. If multiple Resolvers are
|
||||||
@ -76,25 +77,6 @@ func GetDefaultScheme() string {
|
|||||||
return defaultScheme
|
return defaultScheme
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddressType indicates the address type returned by name resolution.
|
|
||||||
//
|
|
||||||
// Deprecated: use Attributes in Address instead.
|
|
||||||
type AddressType uint8
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Backend indicates the address is for a backend server.
|
|
||||||
//
|
|
||||||
// Deprecated: use Attributes in Address instead.
|
|
||||||
Backend AddressType = iota
|
|
||||||
// GRPCLB indicates the address is for a grpclb load balancer.
|
|
||||||
//
|
|
||||||
// Deprecated: to select the GRPCLB load balancing policy, use a service
|
|
||||||
// config with a corresponding loadBalancingConfig. To supply balancer
|
|
||||||
// addresses to the GRPCLB load balancing policy, set State.Attributes
|
|
||||||
// using balancer/grpclb/state.Set.
|
|
||||||
GRPCLB
|
|
||||||
)
|
|
||||||
|
|
||||||
// Address represents a server the client connects to.
|
// Address represents a server the client connects to.
|
||||||
//
|
//
|
||||||
// # Experimental
|
// # Experimental
|
||||||
@ -110,9 +92,6 @@ type Address struct {
|
|||||||
// the address, instead of the hostname from the Dial target string. In most cases,
|
// the address, instead of the hostname from the Dial target string. In most cases,
|
||||||
// this should not be set.
|
// this should not be set.
|
||||||
//
|
//
|
||||||
// If Type is GRPCLB, ServerName should be the name of the remote load
|
|
||||||
// balancer, not the name of the backend.
|
|
||||||
//
|
|
||||||
// WARNING: ServerName must only be populated with trusted values. It
|
// WARNING: ServerName must only be populated with trusted values. It
|
||||||
// is insecure to populate it with data from untrusted inputs since untrusted
|
// is insecure to populate it with data from untrusted inputs since untrusted
|
||||||
// values could be used to bypass the authority checks performed by TLS.
|
// values could be used to bypass the authority checks performed by TLS.
|
||||||
@ -123,34 +102,46 @@ type Address struct {
|
|||||||
Attributes *attributes.Attributes
|
Attributes *attributes.Attributes
|
||||||
|
|
||||||
// BalancerAttributes contains arbitrary data about this address intended
|
// BalancerAttributes contains arbitrary data about this address intended
|
||||||
// for consumption by the LB policy. These attribes do not affect SubConn
|
// for consumption by the LB policy. These attributes do not affect SubConn
|
||||||
// creation, connection establishment, handshaking, etc.
|
// creation, connection establishment, handshaking, etc.
|
||||||
BalancerAttributes *attributes.Attributes
|
|
||||||
|
|
||||||
// Type is the type of this address.
|
|
||||||
//
|
//
|
||||||
// Deprecated: use Attributes instead.
|
// Deprecated: when an Address is inside an Endpoint, this field should not
|
||||||
Type AddressType
|
// be used, and it will eventually be removed entirely.
|
||||||
|
BalancerAttributes *attributes.Attributes
|
||||||
|
|
||||||
// Metadata is the information associated with Addr, which may be used
|
// Metadata is the information associated with Addr, which may be used
|
||||||
// to make load balancing decision.
|
// to make load balancing decision.
|
||||||
//
|
//
|
||||||
// Deprecated: use Attributes instead.
|
// Deprecated: use Attributes instead.
|
||||||
Metadata interface{}
|
Metadata any
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.
|
||||||
|
//
|
||||||
|
// This method compares all fields of the address. When used to tell apart
|
||||||
|
// addresses during subchannel creation or connection establishment, it might be
|
||||||
|
// more appropriate for the caller to implement custom equality logic.
|
||||||
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.Metadata == o.Metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns JSON formatted string representation of the address.
|
// String returns JSON formatted string representation of the address.
|
||||||
func (a Address) String() string {
|
func (a Address) String() string {
|
||||||
return pretty.ToJSON(a)
|
var sb strings.Builder
|
||||||
|
sb.WriteString(fmt.Sprintf("{Addr: %q, ", a.Addr))
|
||||||
|
sb.WriteString(fmt.Sprintf("ServerName: %q, ", a.ServerName))
|
||||||
|
if a.Attributes != nil {
|
||||||
|
sb.WriteString(fmt.Sprintf("Attributes: %v, ", a.Attributes.String()))
|
||||||
|
}
|
||||||
|
if a.BalancerAttributes != nil {
|
||||||
|
sb.WriteString(fmt.Sprintf("BalancerAttributes: %v", a.BalancerAttributes.String()))
|
||||||
|
}
|
||||||
|
sb.WriteString("}")
|
||||||
|
return sb.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildOptions includes additional information for the builder to create
|
// BuildOptions includes additional information for the builder to create
|
||||||
@ -179,11 +170,37 @@ type BuildOptions struct {
|
|||||||
Dialer func(context.Context, string) (net.Conn, error)
|
Dialer func(context.Context, string) (net.Conn, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// An Endpoint is one network endpoint, or server, which may have multiple
|
||||||
|
// addresses with which it can be accessed.
|
||||||
|
type Endpoint struct {
|
||||||
|
// Addresses contains a list of addresses used to access this endpoint.
|
||||||
|
Addresses []Address
|
||||||
|
|
||||||
|
// Attributes contains arbitrary data about this endpoint intended for
|
||||||
|
// consumption by the LB policy.
|
||||||
|
Attributes *attributes.Attributes
|
||||||
|
}
|
||||||
|
|
||||||
// State contains the current Resolver state relevant to the ClientConn.
|
// State contains the current Resolver state relevant to the ClientConn.
|
||||||
type State struct {
|
type State struct {
|
||||||
// Addresses is the latest set of resolved addresses for the target.
|
// Addresses is the latest set of resolved addresses for the target.
|
||||||
|
//
|
||||||
|
// If a resolver sets Addresses but does not set Endpoints, one Endpoint
|
||||||
|
// will be created for each Address before the State is passed to the LB
|
||||||
|
// policy. The BalancerAttributes of each entry in Addresses will be set
|
||||||
|
// in Endpoints.Attributes, and be cleared in the Endpoint's Address's
|
||||||
|
// BalancerAttributes.
|
||||||
|
//
|
||||||
|
// Soon, Addresses will be deprecated and replaced fully by Endpoints.
|
||||||
Addresses []Address
|
Addresses []Address
|
||||||
|
|
||||||
|
// Endpoints is the latest set of resolved endpoints for the target.
|
||||||
|
//
|
||||||
|
// If a resolver produces a State containing Endpoints but not Addresses,
|
||||||
|
// it must take care to ensure the LB policies it selects will support
|
||||||
|
// Endpoints.
|
||||||
|
Endpoints []Endpoint
|
||||||
|
|
||||||
// ServiceConfig contains the result from parsing the latest service
|
// ServiceConfig contains the result from parsing the latest service
|
||||||
// config. If it is nil, it indicates no service config is present or the
|
// config. If it is nil, it indicates no service config is present or the
|
||||||
// resolver does not provide service configs.
|
// resolver does not provide service configs.
|
||||||
@ -203,6 +220,15 @@ type State struct {
|
|||||||
// gRPC to add new methods to this interface.
|
// gRPC to add new methods to this interface.
|
||||||
type ClientConn interface {
|
type ClientConn interface {
|
||||||
// UpdateState updates the state of the ClientConn appropriately.
|
// UpdateState updates the state of the ClientConn appropriately.
|
||||||
|
//
|
||||||
|
// If an error is returned, the resolver should try to resolve the
|
||||||
|
// target again. The resolver should use a backoff timer to prevent
|
||||||
|
// overloading the server with requests. If a resolver is certain that
|
||||||
|
// reresolving will not change the result, e.g. because it is
|
||||||
|
// a watch-based resolver, returned errors can be ignored.
|
||||||
|
//
|
||||||
|
// If the resolved State is the same as the last reported one, calling
|
||||||
|
// UpdateState can be omitted.
|
||||||
UpdateState(State) error
|
UpdateState(State) error
|
||||||
// ReportError notifies the ClientConn that the Resolver encountered an
|
// ReportError notifies the ClientConn that the Resolver encountered an
|
||||||
// error. The ClientConn will notify the load balancer and begin calling
|
// error. The ClientConn will notify the load balancer and begin calling
|
||||||
@ -234,20 +260,7 @@ type ClientConn interface {
|
|||||||
// target does not contain a scheme or if the parsed scheme is not registered
|
// target does not contain a scheme or if the parsed scheme is not registered
|
||||||
// (i.e. no corresponding resolver available to resolve the endpoint), we will
|
// (i.e. no corresponding resolver available to resolve the endpoint), we will
|
||||||
// apply the default scheme, and will attempt to reparse it.
|
// apply the default scheme, and will attempt to reparse it.
|
||||||
//
|
|
||||||
// Examples:
|
|
||||||
//
|
|
||||||
// - "dns://some_authority/foo.bar"
|
|
||||||
// Target{Scheme: "dns", Authority: "some_authority", Endpoint: "foo.bar"}
|
|
||||||
// - "foo.bar"
|
|
||||||
// Target{Scheme: resolver.GetDefaultScheme(), Endpoint: "foo.bar"}
|
|
||||||
// - "unknown_scheme://authority/endpoint"
|
|
||||||
// Target{Scheme: resolver.GetDefaultScheme(), Endpoint: "unknown_scheme://authority/endpoint"}
|
|
||||||
type Target struct {
|
type Target struct {
|
||||||
// Deprecated: use URL.Scheme instead.
|
|
||||||
Scheme string
|
|
||||||
// Deprecated: use URL.Host instead.
|
|
||||||
Authority string
|
|
||||||
// URL contains the parsed dial target with an optional default scheme added
|
// URL contains the parsed dial target with an optional default scheme added
|
||||||
// to it if the original dial target contained no scheme or contained an
|
// to it if the original dial target contained no scheme or contained an
|
||||||
// unregistered scheme. Any query params specified in the original dial
|
// unregistered scheme. Any query params specified in the original dial
|
||||||
@ -280,8 +293,10 @@ type Builder interface {
|
|||||||
// gRPC dial calls Build synchronously, and fails if the returned error is
|
// gRPC dial calls Build synchronously, and fails if the returned error is
|
||||||
// not nil.
|
// not nil.
|
||||||
Build(target Target, cc ClientConn, opts BuildOptions) (Resolver, error)
|
Build(target Target, cc ClientConn, opts BuildOptions) (Resolver, error)
|
||||||
// Scheme returns the scheme supported by this resolver.
|
// Scheme returns the scheme supported by this resolver. Scheme is defined
|
||||||
// Scheme is defined at https://github.com/grpc/grpc/blob/master/doc/naming.md.
|
// at https://github.com/grpc/grpc/blob/master/doc/naming.md. The returned
|
||||||
|
// string should not contain uppercase characters, as they will not match
|
||||||
|
// the parsed target's scheme as defined in RFC 3986.
|
||||||
Scheme() string
|
Scheme() string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,10 +314,3 @@ type Resolver interface {
|
|||||||
// Close closes the resolver.
|
// Close closes the resolver.
|
||||||
Close()
|
Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnregisterForTesting removes the resolver builder with the given scheme from the
|
|
||||||
// resolver map.
|
|
||||||
// This function is for testing only.
|
|
||||||
func UnregisterForTesting(scheme string) {
|
|
||||||
delete(m, scheme)
|
|
||||||
}
|
|
||||||
|
197
vendor/google.golang.org/grpc/resolver_conn_wrapper.go
generated
vendored
197
vendor/google.golang.org/grpc/resolver_conn_wrapper.go
generated
vendored
@ -19,11 +19,11 @@
|
|||||||
package grpc
|
package grpc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"google.golang.org/grpc/balancer"
|
"google.golang.org/grpc/balancer"
|
||||||
"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/internal/pretty"
|
||||||
@ -31,129 +31,200 @@ import (
|
|||||||
"google.golang.org/grpc/serviceconfig"
|
"google.golang.org/grpc/serviceconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// resolverStateUpdater wraps the single method used by ccResolverWrapper to
|
||||||
|
// report a state update from the actual resolver implementation.
|
||||||
|
type resolverStateUpdater interface {
|
||||||
|
updateResolverState(s resolver.State, err error) error
|
||||||
|
}
|
||||||
|
|
||||||
// ccResolverWrapper is a wrapper on top of cc for resolvers.
|
// ccResolverWrapper is a wrapper on top of cc for resolvers.
|
||||||
// It implements resolver.ClientConn interface.
|
// It implements resolver.ClientConn interface.
|
||||||
type ccResolverWrapper struct {
|
type ccResolverWrapper struct {
|
||||||
cc *ClientConn
|
// The following fields are initialized when the wrapper is created and are
|
||||||
resolverMu sync.Mutex
|
// read-only afterwards, and therefore can be accessed without a mutex.
|
||||||
resolver resolver.Resolver
|
cc resolverStateUpdater
|
||||||
done *grpcsync.Event
|
channelzID *channelz.Identifier
|
||||||
|
ignoreServiceConfig bool
|
||||||
|
opts ccResolverWrapperOpts
|
||||||
|
serializer *grpcsync.CallbackSerializer // To serialize all incoming calls.
|
||||||
|
serializerCancel context.CancelFunc // To close the serializer, accessed only from close().
|
||||||
|
|
||||||
|
// All incoming (resolver --> gRPC) calls are guaranteed to execute in a
|
||||||
|
// mutually exclusive manner as they are scheduled on the serializer.
|
||||||
|
// Fields accessed *only* in these serializer callbacks, can therefore be
|
||||||
|
// accessed without a mutex.
|
||||||
curState resolver.State
|
curState resolver.State
|
||||||
|
|
||||||
incomingMu sync.Mutex // Synchronizes all the incoming calls.
|
// mu guards access to the below fields.
|
||||||
|
mu sync.Mutex
|
||||||
|
closed bool
|
||||||
|
resolver resolver.Resolver // Accessed only from outgoing calls.
|
||||||
|
}
|
||||||
|
|
||||||
|
// ccResolverWrapperOpts wraps the arguments to be passed when creating a new
|
||||||
|
// ccResolverWrapper.
|
||||||
|
type ccResolverWrapperOpts struct {
|
||||||
|
target resolver.Target // User specified dial target to resolve.
|
||||||
|
builder resolver.Builder // Resolver builder to use.
|
||||||
|
bOpts resolver.BuildOptions // Resolver build options to use.
|
||||||
|
channelzID *channelz.Identifier // Channelz identifier for the channel.
|
||||||
}
|
}
|
||||||
|
|
||||||
// newCCResolverWrapper uses the resolver.Builder to build a Resolver and
|
// newCCResolverWrapper uses the resolver.Builder to build a Resolver and
|
||||||
// returns a ccResolverWrapper object which wraps the newly built resolver.
|
// returns a ccResolverWrapper object which wraps the newly built resolver.
|
||||||
func newCCResolverWrapper(cc *ClientConn, rb resolver.Builder) (*ccResolverWrapper, error) {
|
func newCCResolverWrapper(cc resolverStateUpdater, opts ccResolverWrapperOpts) (*ccResolverWrapper, error) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
ccr := &ccResolverWrapper{
|
ccr := &ccResolverWrapper{
|
||||||
cc: cc,
|
cc: cc,
|
||||||
done: grpcsync.NewEvent(),
|
channelzID: opts.channelzID,
|
||||||
|
ignoreServiceConfig: opts.bOpts.DisableServiceConfig,
|
||||||
|
opts: opts,
|
||||||
|
serializer: grpcsync.NewCallbackSerializer(ctx),
|
||||||
|
serializerCancel: cancel,
|
||||||
}
|
}
|
||||||
|
|
||||||
var credsClone credentials.TransportCredentials
|
// Cannot hold the lock at build time because the resolver can send an
|
||||||
if creds := cc.dopts.copts.TransportCredentials; creds != nil {
|
// update or error inline and these incoming calls grab the lock to schedule
|
||||||
credsClone = creds.Clone()
|
// a callback in the serializer.
|
||||||
}
|
r, err := opts.builder.Build(opts.target, ccr, opts.bOpts)
|
||||||
rbo := resolver.BuildOptions{
|
|
||||||
DisableServiceConfig: cc.dopts.disableServiceConfig,
|
|
||||||
DialCreds: credsClone,
|
|
||||||
CredsBundle: cc.dopts.copts.CredsBundle,
|
|
||||||
Dialer: cc.dopts.copts.Dialer,
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
|
||||||
// We need to hold the lock here while we assign to the ccr.resolver field
|
|
||||||
// to guard against a data race caused by the following code path,
|
|
||||||
// rb.Build-->ccr.ReportError-->ccr.poll-->ccr.resolveNow, would end up
|
|
||||||
// accessing ccr.resolver which is being assigned here.
|
|
||||||
ccr.resolverMu.Lock()
|
|
||||||
defer ccr.resolverMu.Unlock()
|
|
||||||
ccr.resolver, err = rb.Build(cc.parsedTarget, ccr, rbo)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
cancel()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Any error reported by the resolver at build time that leads to a
|
||||||
|
// re-resolution request from the balancer is dropped by grpc until we
|
||||||
|
// return from this function. So, we don't have to handle pending resolveNow
|
||||||
|
// requests here.
|
||||||
|
ccr.mu.Lock()
|
||||||
|
ccr.resolver = r
|
||||||
|
ccr.mu.Unlock()
|
||||||
|
|
||||||
return ccr, nil
|
return ccr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ccr *ccResolverWrapper) resolveNow(o resolver.ResolveNowOptions) {
|
func (ccr *ccResolverWrapper) resolveNow(o resolver.ResolveNowOptions) {
|
||||||
ccr.resolverMu.Lock()
|
ccr.mu.Lock()
|
||||||
if !ccr.done.HasFired() {
|
defer ccr.mu.Unlock()
|
||||||
ccr.resolver.ResolveNow(o)
|
|
||||||
|
// ccr.resolver field is set only after the call to Build() returns. But in
|
||||||
|
// the process of building, the resolver may send an error update which when
|
||||||
|
// propagated to the balancer may result in a re-resolution request.
|
||||||
|
if ccr.closed || ccr.resolver == nil {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
ccr.resolverMu.Unlock()
|
ccr.resolver.ResolveNow(o)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ccr *ccResolverWrapper) close() {
|
func (ccr *ccResolverWrapper) close() {
|
||||||
ccr.resolverMu.Lock()
|
ccr.mu.Lock()
|
||||||
ccr.resolver.Close()
|
if ccr.closed {
|
||||||
ccr.done.Fire()
|
ccr.mu.Unlock()
|
||||||
ccr.resolverMu.Unlock()
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ccr *ccResolverWrapper) UpdateState(s resolver.State) error {
|
channelz.Info(logger, ccr.channelzID, "Closing the name resolver")
|
||||||
ccr.incomingMu.Lock()
|
|
||||||
defer ccr.incomingMu.Unlock()
|
// Close the serializer to ensure that no more calls from the resolver are
|
||||||
if ccr.done.HasFired() {
|
// handled, before actually closing the resolver.
|
||||||
return nil
|
ccr.serializerCancel()
|
||||||
|
ccr.closed = true
|
||||||
|
r := ccr.resolver
|
||||||
|
ccr.mu.Unlock()
|
||||||
|
|
||||||
|
// Give enqueued callbacks a chance to finish.
|
||||||
|
<-ccr.serializer.Done()
|
||||||
|
|
||||||
|
// Spawn a goroutine to close the resolver (since it may block trying to
|
||||||
|
// cleanup all allocated resources) and return early.
|
||||||
|
go r.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// serializerScheduleLocked is a convenience method to schedule a function to be
|
||||||
|
// run on the serializer while holding ccr.mu.
|
||||||
|
func (ccr *ccResolverWrapper) serializerScheduleLocked(f func(context.Context)) {
|
||||||
|
ccr.mu.Lock()
|
||||||
|
ccr.serializer.Schedule(f)
|
||||||
|
ccr.mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateState is called by resolver implementations to report new state to gRPC
|
||||||
|
// which includes addresses and service config.
|
||||||
|
func (ccr *ccResolverWrapper) UpdateState(s resolver.State) error {
|
||||||
|
errCh := make(chan error, 1)
|
||||||
|
if s.Endpoints == nil {
|
||||||
|
s.Endpoints = make([]resolver.Endpoint, 0, len(s.Addresses))
|
||||||
|
for _, a := range s.Addresses {
|
||||||
|
ep := resolver.Endpoint{Addresses: []resolver.Address{a}, Attributes: a.BalancerAttributes}
|
||||||
|
ep.Addresses[0].BalancerAttributes = nil
|
||||||
|
s.Endpoints = append(s.Endpoints, ep)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ok := ccr.serializer.Schedule(func(context.Context) {
|
||||||
ccr.addChannelzTraceEvent(s)
|
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
|
errCh <- balancer.ErrBadResolverState
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
errCh <- nil
|
||||||
|
})
|
||||||
|
if !ok {
|
||||||
|
// The only time when Schedule() fail to add the callback to the
|
||||||
|
// serializer is when the serializer is closed, and this happens only
|
||||||
|
// when the resolver wrapper is closed.
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
return <-errCh
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReportError is called by resolver implementations to report errors
|
||||||
|
// encountered during name resolution to gRPC.
|
||||||
func (ccr *ccResolverWrapper) ReportError(err error) {
|
func (ccr *ccResolverWrapper) ReportError(err error) {
|
||||||
ccr.incomingMu.Lock()
|
ccr.serializerScheduleLocked(func(_ context.Context) {
|
||||||
defer ccr.incomingMu.Unlock()
|
channelz.Warningf(logger, ccr.channelzID, "ccResolverWrapper: reporting error to cc: %v", err)
|
||||||
if ccr.done.HasFired() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
channelz.Warningf(logger, ccr.cc.channelzID, "ccResolverWrapper: reporting error to cc: %v", err)
|
|
||||||
ccr.cc.updateResolverState(resolver.State{}, err)
|
ccr.cc.updateResolverState(resolver.State{}, err)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAddress is called by the resolver implementation to send addresses to gRPC.
|
// NewAddress is called by the resolver implementation to send addresses to
|
||||||
|
// gRPC.
|
||||||
func (ccr *ccResolverWrapper) NewAddress(addrs []resolver.Address) {
|
func (ccr *ccResolverWrapper) NewAddress(addrs []resolver.Address) {
|
||||||
ccr.incomingMu.Lock()
|
ccr.serializerScheduleLocked(func(_ context.Context) {
|
||||||
defer ccr.incomingMu.Unlock()
|
|
||||||
if ccr.done.HasFired() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ccr.addChannelzTraceEvent(resolver.State{Addresses: addrs, ServiceConfig: ccr.curState.ServiceConfig})
|
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)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewServiceConfig is called by the resolver implementation to send service
|
// NewServiceConfig is called by the resolver implementation to send service
|
||||||
// configs to gRPC.
|
// configs to gRPC.
|
||||||
func (ccr *ccResolverWrapper) NewServiceConfig(sc string) {
|
func (ccr *ccResolverWrapper) NewServiceConfig(sc string) {
|
||||||
ccr.incomingMu.Lock()
|
ccr.serializerScheduleLocked(func(_ context.Context) {
|
||||||
defer ccr.incomingMu.Unlock()
|
channelz.Infof(logger, ccr.channelzID, "ccResolverWrapper: got new service config: %s", sc)
|
||||||
if ccr.done.HasFired() {
|
if ccr.ignoreServiceConfig {
|
||||||
return
|
channelz.Info(logger, ccr.channelzID, "Service config lookups disabled; ignoring config")
|
||||||
}
|
|
||||||
channelz.Infof(logger, ccr.cc.channelzID, "ccResolverWrapper: got new service config: %s", sc)
|
|
||||||
if ccr.cc.dopts.disableServiceConfig {
|
|
||||||
channelz.Info(logger, ccr.cc.channelzID, "Service config lookups disabled; ignoring config")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
scpr := parseServiceConfig(sc)
|
scpr := parseServiceConfig(sc)
|
||||||
if scpr.Err != nil {
|
if scpr.Err != nil {
|
||||||
channelz.Warningf(logger, ccr.cc.channelzID, "ccResolverWrapper: error parsing service config: %v", scpr.Err)
|
channelz.Warningf(logger, ccr.channelzID, "ccResolverWrapper: error parsing service config: %v", scpr.Err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
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)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParseServiceConfig is called by resolver implementations to parse a JSON
|
||||||
|
// representation of the service config.
|
||||||
func (ccr *ccResolverWrapper) ParseServiceConfig(scJSON string) *serviceconfig.ParseResult {
|
func (ccr *ccResolverWrapper) ParseServiceConfig(scJSON string) *serviceconfig.ParseResult {
|
||||||
return parseServiceConfig(scJSON)
|
return parseServiceConfig(scJSON)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// addChannelzTraceEvent adds a channelz trace event containing the new
|
||||||
|
// state received from resolver implementations.
|
||||||
func (ccr *ccResolverWrapper) addChannelzTraceEvent(s resolver.State) {
|
func (ccr *ccResolverWrapper) addChannelzTraceEvent(s resolver.State) {
|
||||||
var updates []string
|
var updates []string
|
||||||
var oldSC, newSC *ServiceConfig
|
var oldSC, newSC *ServiceConfig
|
||||||
@ -172,5 +243,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.Infof(logger, ccr.cc.channelzID, "Resolver state updated: %s (%v)", pretty.ToJSON(s), strings.Join(updates, "; "))
|
channelz.Infof(logger, ccr.channelzID, "Resolver state updated: %s (%v)", pretty.ToJSON(s), strings.Join(updates, "; "))
|
||||||
}
|
}
|
||||||
|
83
vendor/google.golang.org/grpc/rpc_util.go
generated
vendored
83
vendor/google.golang.org/grpc/rpc_util.go
generated
vendored
@ -75,7 +75,7 @@ func NewGZIPCompressorWithLevel(level int) (Compressor, error) {
|
|||||||
}
|
}
|
||||||
return &gzipCompressor{
|
return &gzipCompressor{
|
||||||
pool: sync.Pool{
|
pool: sync.Pool{
|
||||||
New: func() interface{} {
|
New: func() any {
|
||||||
w, err := gzip.NewWriterLevel(io.Discard, level)
|
w, err := gzip.NewWriterLevel(io.Discard, level)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -159,6 +159,7 @@ type callInfo struct {
|
|||||||
contentSubtype string
|
contentSubtype string
|
||||||
codec baseCodec
|
codec baseCodec
|
||||||
maxRetryRPCBufferSize int
|
maxRetryRPCBufferSize int
|
||||||
|
onFinish []func(err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func defaultCallInfo() *callInfo {
|
func defaultCallInfo() *callInfo {
|
||||||
@ -295,6 +296,41 @@ func (o FailFastCallOption) before(c *callInfo) error {
|
|||||||
}
|
}
|
||||||
func (o FailFastCallOption) after(c *callInfo, attempt *csAttempt) {}
|
func (o FailFastCallOption) after(c *callInfo, attempt *csAttempt) {}
|
||||||
|
|
||||||
|
// OnFinish returns a CallOption that configures a callback to be called when
|
||||||
|
// the call completes. The error passed to the callback is the status of the
|
||||||
|
// RPC, and may be nil. The onFinish callback provided will only be called once
|
||||||
|
// by gRPC. This is mainly used to be used by streaming interceptors, to be
|
||||||
|
// notified when the RPC completes along with information about the status of
|
||||||
|
// the RPC.
|
||||||
|
//
|
||||||
|
// # Experimental
|
||||||
|
//
|
||||||
|
// Notice: This API is EXPERIMENTAL and may be changed or removed in a
|
||||||
|
// later release.
|
||||||
|
func OnFinish(onFinish func(err error)) CallOption {
|
||||||
|
return OnFinishCallOption{
|
||||||
|
OnFinish: onFinish,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnFinishCallOption is CallOption that indicates a callback to be called when
|
||||||
|
// the call completes.
|
||||||
|
//
|
||||||
|
// # Experimental
|
||||||
|
//
|
||||||
|
// Notice: This type is EXPERIMENTAL and may be changed or removed in a
|
||||||
|
// later release.
|
||||||
|
type OnFinishCallOption struct {
|
||||||
|
OnFinish func(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o OnFinishCallOption) before(c *callInfo) error {
|
||||||
|
c.onFinish = append(c.onFinish, o.OnFinish)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o OnFinishCallOption) after(c *callInfo, attempt *csAttempt) {}
|
||||||
|
|
||||||
// MaxCallRecvMsgSize returns a CallOption which sets the maximum message size
|
// MaxCallRecvMsgSize returns a CallOption which sets the maximum message size
|
||||||
// in bytes the client can receive. If this is not set, gRPC uses the default
|
// in bytes the client can receive. If this is not set, gRPC uses the default
|
||||||
// 4MB.
|
// 4MB.
|
||||||
@ -541,6 +577,9 @@ type parser struct {
|
|||||||
// The header of a gRPC message. Find more detail at
|
// The header of a gRPC message. Find more detail at
|
||||||
// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md
|
// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md
|
||||||
header [5]byte
|
header [5]byte
|
||||||
|
|
||||||
|
// recvBufferPool is the pool of shared receive buffers.
|
||||||
|
recvBufferPool SharedBufferPool
|
||||||
}
|
}
|
||||||
|
|
||||||
// recvMsg reads a complete gRPC message from the stream.
|
// recvMsg reads a complete gRPC message from the stream.
|
||||||
@ -574,9 +613,7 @@ func (p *parser) recvMsg(maxReceiveMessageSize int) (pf payloadFormat, msg []byt
|
|||||||
if int(length) > maxReceiveMessageSize {
|
if int(length) > maxReceiveMessageSize {
|
||||||
return 0, nil, status.Errorf(codes.ResourceExhausted, "grpc: received message larger than max (%d vs. %d)", length, maxReceiveMessageSize)
|
return 0, nil, status.Errorf(codes.ResourceExhausted, "grpc: received message larger than max (%d vs. %d)", length, maxReceiveMessageSize)
|
||||||
}
|
}
|
||||||
// TODO(bradfitz,zhaoq): garbage. reuse buffer after proto decoding instead
|
msg = p.recvBufferPool.Get(int(length))
|
||||||
// of making it for each message:
|
|
||||||
msg = make([]byte, int(length))
|
|
||||||
if _, err := p.r.Read(msg); err != nil {
|
if _, err := p.r.Read(msg); err != nil {
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
err = io.ErrUnexpectedEOF
|
err = io.ErrUnexpectedEOF
|
||||||
@ -589,7 +626,7 @@ func (p *parser) recvMsg(maxReceiveMessageSize int) (pf payloadFormat, msg []byt
|
|||||||
// encode serializes msg and returns a buffer containing the message, or an
|
// encode serializes msg and returns a buffer containing the message, or an
|
||||||
// error if it is too large to be transmitted by grpc. If msg is nil, it
|
// error if it is too large to be transmitted by grpc. If msg is nil, it
|
||||||
// generates an empty message.
|
// generates an empty message.
|
||||||
func encode(c baseCodec, msg interface{}) ([]byte, error) {
|
func encode(c baseCodec, msg any) ([]byte, error) {
|
||||||
if msg == nil { // NOTE: typed nils will not be caught by this check
|
if msg == nil { // NOTE: typed nils will not be caught by this check
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@ -656,13 +693,14 @@ func msgHeader(data, compData []byte) (hdr []byte, payload []byte) {
|
|||||||
return hdr, data
|
return hdr, data
|
||||||
}
|
}
|
||||||
|
|
||||||
func outPayload(client bool, msg interface{}, data, payload []byte, t time.Time) *stats.OutPayload {
|
func outPayload(client bool, msg any, data, payload []byte, t time.Time) *stats.OutPayload {
|
||||||
return &stats.OutPayload{
|
return &stats.OutPayload{
|
||||||
Client: client,
|
Client: client,
|
||||||
Payload: msg,
|
Payload: msg,
|
||||||
Data: data,
|
Data: data,
|
||||||
Length: len(data),
|
Length: len(data),
|
||||||
WireLength: len(payload) + headerLen,
|
WireLength: len(payload) + headerLen,
|
||||||
|
CompressedLength: len(payload),
|
||||||
SentTime: t,
|
SentTime: t,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -684,17 +722,17 @@ func checkRecvPayload(pf payloadFormat, recvCompress string, haveCompressor bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
type payloadInfo struct {
|
type payloadInfo struct {
|
||||||
wireLength int // The compressed length got from wire.
|
compressedLength int // The compressed length got from wire.
|
||||||
uncompressedBytes []byte
|
uncompressedBytes []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func recvAndDecompress(p *parser, s *transport.Stream, dc Decompressor, maxReceiveMessageSize int, payInfo *payloadInfo, compressor encoding.Compressor) ([]byte, error) {
|
func recvAndDecompress(p *parser, s *transport.Stream, dc Decompressor, maxReceiveMessageSize int, payInfo *payloadInfo, compressor encoding.Compressor) ([]byte, error) {
|
||||||
pf, d, err := p.recvMsg(maxReceiveMessageSize)
|
pf, buf, err := p.recvMsg(maxReceiveMessageSize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if payInfo != nil {
|
if payInfo != nil {
|
||||||
payInfo.wireLength = len(d)
|
payInfo.compressedLength = len(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if st := checkRecvPayload(pf, s.RecvCompress(), compressor != nil || dc != nil); st != nil {
|
if st := checkRecvPayload(pf, s.RecvCompress(), compressor != nil || dc != nil); st != nil {
|
||||||
@ -706,10 +744,10 @@ func recvAndDecompress(p *parser, s *transport.Stream, dc Decompressor, maxRecei
|
|||||||
// To match legacy behavior, if the decompressor is set by WithDecompressor or RPCDecompressor,
|
// To match legacy behavior, if the decompressor is set by WithDecompressor or RPCDecompressor,
|
||||||
// use this decompressor as the default.
|
// use this decompressor as the default.
|
||||||
if dc != nil {
|
if dc != nil {
|
||||||
d, err = dc.Do(bytes.NewReader(d))
|
buf, err = dc.Do(bytes.NewReader(buf))
|
||||||
size = len(d)
|
size = len(buf)
|
||||||
} else {
|
} else {
|
||||||
d, size, err = decompress(compressor, d, maxReceiveMessageSize)
|
buf, size, err = decompress(compressor, buf, maxReceiveMessageSize)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message: %v", err)
|
return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message: %v", err)
|
||||||
@ -720,7 +758,7 @@ func recvAndDecompress(p *parser, s *transport.Stream, dc Decompressor, maxRecei
|
|||||||
return nil, status.Errorf(codes.ResourceExhausted, "grpc: received message after decompression larger than max (%d vs. %d)", size, maxReceiveMessageSize)
|
return nil, status.Errorf(codes.ResourceExhausted, "grpc: received message after decompression larger than max (%d vs. %d)", size, maxReceiveMessageSize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return d, nil
|
return buf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Using compressor, decompress d, returning data and size.
|
// Using compressor, decompress d, returning data and size.
|
||||||
@ -754,16 +792,18 @@ func decompress(compressor encoding.Compressor, d []byte, maxReceiveMessageSize
|
|||||||
// For the two compressor parameters, both should not be set, but if they are,
|
// For the two compressor parameters, both should not be set, but if they are,
|
||||||
// dc takes precedence over compressor.
|
// dc takes precedence over compressor.
|
||||||
// TODO(dfawley): wrap the old compressor/decompressor using the new API?
|
// TODO(dfawley): wrap the old compressor/decompressor using the new API?
|
||||||
func recv(p *parser, c baseCodec, s *transport.Stream, dc Decompressor, m interface{}, maxReceiveMessageSize int, payInfo *payloadInfo, compressor encoding.Compressor) error {
|
func recv(p *parser, c baseCodec, s *transport.Stream, dc Decompressor, m any, maxReceiveMessageSize int, payInfo *payloadInfo, compressor encoding.Compressor) error {
|
||||||
d, err := recvAndDecompress(p, s, dc, maxReceiveMessageSize, payInfo, compressor)
|
buf, err := recvAndDecompress(p, s, dc, maxReceiveMessageSize, payInfo, compressor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := c.Unmarshal(d, m); err != nil {
|
if err := c.Unmarshal(buf, m); err != nil {
|
||||||
return status.Errorf(codes.Internal, "grpc: failed to unmarshal the received message: %v", err)
|
return status.Errorf(codes.Internal, "grpc: failed to unmarshal the received message: %v", err)
|
||||||
}
|
}
|
||||||
if payInfo != nil {
|
if payInfo != nil {
|
||||||
payInfo.uncompressedBytes = d
|
payInfo.uncompressedBytes = buf
|
||||||
|
} else {
|
||||||
|
p.recvBufferPool.Put(&buf)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -823,19 +863,22 @@ func ErrorDesc(err error) string {
|
|||||||
// Errorf returns nil if c is OK.
|
// Errorf returns nil if c is OK.
|
||||||
//
|
//
|
||||||
// Deprecated: use status.Errorf instead.
|
// Deprecated: use status.Errorf instead.
|
||||||
func Errorf(c codes.Code, format string, a ...interface{}) error {
|
func Errorf(c codes.Code, format string, a ...any) error {
|
||||||
return status.Errorf(c, format, a...)
|
return status.Errorf(c, format, a...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var errContextCanceled = status.Error(codes.Canceled, context.Canceled.Error())
|
||||||
|
var errContextDeadline = status.Error(codes.DeadlineExceeded, context.DeadlineExceeded.Error())
|
||||||
|
|
||||||
// toRPCErr converts an error into an error from the status package.
|
// toRPCErr converts an error into an error from the status package.
|
||||||
func toRPCErr(err error) error {
|
func toRPCErr(err error) error {
|
||||||
switch err {
|
switch err {
|
||||||
case nil, io.EOF:
|
case nil, io.EOF:
|
||||||
return err
|
return err
|
||||||
case context.DeadlineExceeded:
|
case context.DeadlineExceeded:
|
||||||
return status.Error(codes.DeadlineExceeded, err.Error())
|
return errContextDeadline
|
||||||
case context.Canceled:
|
case context.Canceled:
|
||||||
return status.Error(codes.Canceled, err.Error())
|
return errContextCanceled
|
||||||
case io.ErrUnexpectedEOF:
|
case io.ErrUnexpectedEOF:
|
||||||
return status.Error(codes.Internal, err.Error())
|
return status.Error(codes.Internal, err.Error())
|
||||||
}
|
}
|
||||||
|
345
vendor/google.golang.org/grpc/server.go
generated
vendored
345
vendor/google.golang.org/grpc/server.go
generated
vendored
@ -43,8 +43,8 @@ import (
|
|||||||
"google.golang.org/grpc/internal"
|
"google.golang.org/grpc/internal"
|
||||||
"google.golang.org/grpc/internal/binarylog"
|
"google.golang.org/grpc/internal/binarylog"
|
||||||
"google.golang.org/grpc/internal/channelz"
|
"google.golang.org/grpc/internal/channelz"
|
||||||
"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/transport"
|
"google.golang.org/grpc/internal/transport"
|
||||||
"google.golang.org/grpc/keepalive"
|
"google.golang.org/grpc/keepalive"
|
||||||
"google.golang.org/grpc/metadata"
|
"google.golang.org/grpc/metadata"
|
||||||
@ -74,10 +74,10 @@ func init() {
|
|||||||
srv.drainServerTransports(addr)
|
srv.drainServerTransports(addr)
|
||||||
}
|
}
|
||||||
internal.AddGlobalServerOptions = func(opt ...ServerOption) {
|
internal.AddGlobalServerOptions = func(opt ...ServerOption) {
|
||||||
extraServerOptions = append(extraServerOptions, opt...)
|
globalServerOptions = append(globalServerOptions, opt...)
|
||||||
}
|
}
|
||||||
internal.ClearGlobalServerOptions = func() {
|
internal.ClearGlobalServerOptions = func() {
|
||||||
extraServerOptions = nil
|
globalServerOptions = nil
|
||||||
}
|
}
|
||||||
internal.BinaryLogger = binaryLogger
|
internal.BinaryLogger = binaryLogger
|
||||||
internal.JoinServerOptions = newJoinServerOption
|
internal.JoinServerOptions = newJoinServerOption
|
||||||
@ -86,7 +86,7 @@ func init() {
|
|||||||
var statusOK = status.New(codes.OK, "")
|
var statusOK = status.New(codes.OK, "")
|
||||||
var logger = grpclog.Component("core")
|
var logger = grpclog.Component("core")
|
||||||
|
|
||||||
type methodHandler func(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor UnaryServerInterceptor) (interface{}, error)
|
type methodHandler func(srv any, ctx context.Context, dec func(any) error, interceptor UnaryServerInterceptor) (any, error)
|
||||||
|
|
||||||
// MethodDesc represents an RPC service's method specification.
|
// MethodDesc represents an RPC service's method specification.
|
||||||
type MethodDesc struct {
|
type MethodDesc struct {
|
||||||
@ -99,26 +99,20 @@ type ServiceDesc struct {
|
|||||||
ServiceName string
|
ServiceName string
|
||||||
// The pointer to the service interface. Used to check whether the user
|
// The pointer to the service interface. Used to check whether the user
|
||||||
// provided implementation satisfies the interface requirements.
|
// provided implementation satisfies the interface requirements.
|
||||||
HandlerType interface{}
|
HandlerType any
|
||||||
Methods []MethodDesc
|
Methods []MethodDesc
|
||||||
Streams []StreamDesc
|
Streams []StreamDesc
|
||||||
Metadata interface{}
|
Metadata any
|
||||||
}
|
}
|
||||||
|
|
||||||
// serviceInfo wraps information about a service. It is very similar to
|
// serviceInfo wraps information about a service. It is very similar to
|
||||||
// ServiceDesc and is constructed from it for internal purposes.
|
// ServiceDesc and is constructed from it for internal purposes.
|
||||||
type serviceInfo struct {
|
type serviceInfo struct {
|
||||||
// Contains the implementation for the methods in this service.
|
// Contains the implementation for the methods in this service.
|
||||||
serviceImpl interface{}
|
serviceImpl any
|
||||||
methods map[string]*MethodDesc
|
methods map[string]*MethodDesc
|
||||||
streams map[string]*StreamDesc
|
streams map[string]*StreamDesc
|
||||||
mdata interface{}
|
mdata any
|
||||||
}
|
|
||||||
|
|
||||||
type serverWorkerData struct {
|
|
||||||
st transport.ServerTransport
|
|
||||||
wg *sync.WaitGroup
|
|
||||||
stream *transport.Stream
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Server is a gRPC server to serve RPC requests.
|
// Server is a gRPC server to serve RPC requests.
|
||||||
@ -145,7 +139,7 @@ type Server struct {
|
|||||||
channelzID *channelz.Identifier
|
channelzID *channelz.Identifier
|
||||||
czData *channelzData
|
czData *channelzData
|
||||||
|
|
||||||
serverWorkerChannels []chan *serverWorkerData
|
serverWorkerChannel chan func()
|
||||||
}
|
}
|
||||||
|
|
||||||
type serverOptions struct {
|
type serverOptions struct {
|
||||||
@ -170,20 +164,24 @@ type serverOptions struct {
|
|||||||
initialConnWindowSize int32
|
initialConnWindowSize int32
|
||||||
writeBufferSize int
|
writeBufferSize int
|
||||||
readBufferSize int
|
readBufferSize int
|
||||||
|
sharedWriteBuffer bool
|
||||||
connectionTimeout time.Duration
|
connectionTimeout time.Duration
|
||||||
maxHeaderListSize *uint32
|
maxHeaderListSize *uint32
|
||||||
headerTableSize *uint32
|
headerTableSize *uint32
|
||||||
numServerWorkers uint32
|
numServerWorkers uint32
|
||||||
|
recvBufferPool SharedBufferPool
|
||||||
}
|
}
|
||||||
|
|
||||||
var defaultServerOptions = serverOptions{
|
var defaultServerOptions = serverOptions{
|
||||||
|
maxConcurrentStreams: math.MaxUint32,
|
||||||
maxReceiveMessageSize: defaultServerMaxReceiveMessageSize,
|
maxReceiveMessageSize: defaultServerMaxReceiveMessageSize,
|
||||||
maxSendMessageSize: defaultServerMaxSendMessageSize,
|
maxSendMessageSize: defaultServerMaxSendMessageSize,
|
||||||
connectionTimeout: 120 * time.Second,
|
connectionTimeout: 120 * time.Second,
|
||||||
writeBufferSize: defaultWriteBufSize,
|
writeBufferSize: defaultWriteBufSize,
|
||||||
readBufferSize: defaultReadBufSize,
|
readBufferSize: defaultReadBufSize,
|
||||||
|
recvBufferPool: nopBufferPool{},
|
||||||
}
|
}
|
||||||
var extraServerOptions []ServerOption
|
var globalServerOptions []ServerOption
|
||||||
|
|
||||||
// A ServerOption sets options such as credentials, codec and keepalive parameters, etc.
|
// A ServerOption sets options such as credentials, codec and keepalive parameters, etc.
|
||||||
type ServerOption interface {
|
type ServerOption interface {
|
||||||
@ -233,6 +231,20 @@ func newJoinServerOption(opts ...ServerOption) ServerOption {
|
|||||||
return &joinServerOption{opts: opts}
|
return &joinServerOption{opts: opts}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SharedWriteBuffer allows reusing per-connection transport write buffer.
|
||||||
|
// If this option is set to true every connection will release the buffer after
|
||||||
|
// flushing the data on the wire.
|
||||||
|
//
|
||||||
|
// # Experimental
|
||||||
|
//
|
||||||
|
// Notice: This API is EXPERIMENTAL and may be changed or removed in a
|
||||||
|
// later release.
|
||||||
|
func SharedWriteBuffer(val bool) ServerOption {
|
||||||
|
return newFuncServerOption(func(o *serverOptions) {
|
||||||
|
o.sharedWriteBuffer = val
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// WriteBufferSize determines how much data can be batched before doing a write
|
// WriteBufferSize determines how much data can be batched before doing a write
|
||||||
// on the wire. The corresponding memory allocation for this buffer will be
|
// on the wire. The corresponding memory allocation for this buffer will be
|
||||||
// twice the size to keep syscalls low. The default value for this buffer is
|
// twice the size to keep syscalls low. The default value for this buffer is
|
||||||
@ -273,9 +285,9 @@ func InitialConnWindowSize(s int32) ServerOption {
|
|||||||
|
|
||||||
// KeepaliveParams returns a ServerOption that sets keepalive and max-age parameters for the server.
|
// KeepaliveParams returns a ServerOption that sets keepalive and max-age parameters for the server.
|
||||||
func KeepaliveParams(kp keepalive.ServerParameters) ServerOption {
|
func KeepaliveParams(kp keepalive.ServerParameters) ServerOption {
|
||||||
if kp.Time > 0 && kp.Time < time.Second {
|
if kp.Time > 0 && kp.Time < internal.KeepaliveMinServerPingTime {
|
||||||
logger.Warning("Adjusting keepalive ping interval to minimum period of 1s")
|
logger.Warning("Adjusting keepalive ping interval to minimum period of 1s")
|
||||||
kp.Time = time.Second
|
kp.Time = internal.KeepaliveMinServerPingTime
|
||||||
}
|
}
|
||||||
|
|
||||||
return newFuncServerOption(func(o *serverOptions) {
|
return newFuncServerOption(func(o *serverOptions) {
|
||||||
@ -387,6 +399,9 @@ func MaxSendMsgSize(m int) ServerOption {
|
|||||||
// MaxConcurrentStreams returns a ServerOption that will apply a limit on the number
|
// MaxConcurrentStreams returns a ServerOption that will apply a limit on the number
|
||||||
// of concurrent streams to each ServerTransport.
|
// of concurrent streams to each ServerTransport.
|
||||||
func MaxConcurrentStreams(n uint32) ServerOption {
|
func MaxConcurrentStreams(n uint32) ServerOption {
|
||||||
|
if n == 0 {
|
||||||
|
n = math.MaxUint32
|
||||||
|
}
|
||||||
return newFuncServerOption(func(o *serverOptions) {
|
return newFuncServerOption(func(o *serverOptions) {
|
||||||
o.maxConcurrentStreams = n
|
o.maxConcurrentStreams = n
|
||||||
})
|
})
|
||||||
@ -552,6 +567,27 @@ func NumStreamWorkers(numServerWorkers uint32) ServerOption {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RecvBufferPool returns a ServerOption that configures the server
|
||||||
|
// to use the provided shared buffer pool for parsing incoming messages. Depending
|
||||||
|
// on the application's workload, this could result in reduced memory allocation.
|
||||||
|
//
|
||||||
|
// If you are unsure about how to implement a memory pool but want to utilize one,
|
||||||
|
// begin with grpc.NewSharedBufferPool.
|
||||||
|
//
|
||||||
|
// Note: The shared buffer pool feature will not be active if any of the following
|
||||||
|
// options are used: StatsHandler, EnableTracing, or binary logging. In such
|
||||||
|
// cases, the shared buffer pool will be ignored.
|
||||||
|
//
|
||||||
|
// # Experimental
|
||||||
|
//
|
||||||
|
// Notice: This API is EXPERIMENTAL and may be changed or removed in a
|
||||||
|
// later release.
|
||||||
|
func RecvBufferPool(bufferPool SharedBufferPool) ServerOption {
|
||||||
|
return newFuncServerOption(func(o *serverOptions) {
|
||||||
|
o.recvBufferPool = bufferPool
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// serverWorkerResetThreshold defines how often the stack must be reset. Every
|
// serverWorkerResetThreshold defines how often the stack must be reset. Every
|
||||||
// N requests, by spawning a new goroutine in its place, a worker can reset its
|
// N requests, by spawning a new goroutine in its place, a worker can reset its
|
||||||
// stack so that large stacks don't live in memory forever. 2^16 should allow
|
// stack so that large stacks don't live in memory forever. 2^16 should allow
|
||||||
@ -560,47 +596,40 @@ func NumStreamWorkers(numServerWorkers uint32) ServerOption {
|
|||||||
const serverWorkerResetThreshold = 1 << 16
|
const serverWorkerResetThreshold = 1 << 16
|
||||||
|
|
||||||
// serverWorkers blocks on a *transport.Stream channel forever and waits for
|
// serverWorkers blocks on a *transport.Stream channel forever and waits for
|
||||||
// data to be fed by serveStreams. This allows different requests to be
|
// data to be fed by serveStreams. This allows multiple requests to be
|
||||||
// processed by the same goroutine, removing the need for expensive stack
|
// processed by the same goroutine, removing the need for expensive stack
|
||||||
// re-allocations (see the runtime.morestack problem [1]).
|
// re-allocations (see the runtime.morestack problem [1]).
|
||||||
//
|
//
|
||||||
// [1] https://github.com/golang/go/issues/18138
|
// [1] https://github.com/golang/go/issues/18138
|
||||||
func (s *Server) serverWorker(ch chan *serverWorkerData) {
|
func (s *Server) serverWorker() {
|
||||||
// To make sure all server workers don't reset at the same time, choose a
|
for completed := 0; completed < serverWorkerResetThreshold; completed++ {
|
||||||
// random number of iterations before resetting.
|
f, ok := <-s.serverWorkerChannel
|
||||||
threshold := serverWorkerResetThreshold + grpcrand.Intn(serverWorkerResetThreshold)
|
|
||||||
for completed := 0; completed < threshold; completed++ {
|
|
||||||
data, ok := <-ch
|
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.handleStream(data.st, data.stream, s.traceInfo(data.st, data.stream))
|
f()
|
||||||
data.wg.Done()
|
|
||||||
}
|
}
|
||||||
go s.serverWorker(ch)
|
go s.serverWorker()
|
||||||
}
|
}
|
||||||
|
|
||||||
// initServerWorkers creates worker goroutines and channels to process incoming
|
// initServerWorkers creates worker goroutines and a channel to process incoming
|
||||||
// connections to reduce the time spent overall on runtime.morestack.
|
// connections to reduce the time spent overall on runtime.morestack.
|
||||||
func (s *Server) initServerWorkers() {
|
func (s *Server) initServerWorkers() {
|
||||||
s.serverWorkerChannels = make([]chan *serverWorkerData, s.opts.numServerWorkers)
|
s.serverWorkerChannel = make(chan func())
|
||||||
for i := uint32(0); i < s.opts.numServerWorkers; i++ {
|
for i := uint32(0); i < s.opts.numServerWorkers; i++ {
|
||||||
s.serverWorkerChannels[i] = make(chan *serverWorkerData)
|
go s.serverWorker()
|
||||||
go s.serverWorker(s.serverWorkerChannels[i])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) stopServerWorkers() {
|
func (s *Server) stopServerWorkers() {
|
||||||
for i := uint32(0); i < s.opts.numServerWorkers; i++ {
|
close(s.serverWorkerChannel)
|
||||||
close(s.serverWorkerChannels[i])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewServer creates a gRPC server which has no service registered and has not
|
// NewServer creates a gRPC server which has no service registered and has not
|
||||||
// started to accept requests yet.
|
// started to accept requests yet.
|
||||||
func NewServer(opt ...ServerOption) *Server {
|
func NewServer(opt ...ServerOption) *Server {
|
||||||
opts := defaultServerOptions
|
opts := defaultServerOptions
|
||||||
for _, o := range extraServerOptions {
|
for _, o := range globalServerOptions {
|
||||||
o.apply(&opts)
|
o.apply(&opts)
|
||||||
}
|
}
|
||||||
for _, o := range opt {
|
for _, o := range opt {
|
||||||
@ -634,7 +663,7 @@ func NewServer(opt ...ServerOption) *Server {
|
|||||||
|
|
||||||
// printf records an event in s's event log, unless s has been stopped.
|
// printf records an event in s's event log, unless s has been stopped.
|
||||||
// REQUIRES s.mu is held.
|
// REQUIRES s.mu is held.
|
||||||
func (s *Server) printf(format string, a ...interface{}) {
|
func (s *Server) printf(format string, a ...any) {
|
||||||
if s.events != nil {
|
if s.events != nil {
|
||||||
s.events.Printf(format, a...)
|
s.events.Printf(format, a...)
|
||||||
}
|
}
|
||||||
@ -642,7 +671,7 @@ func (s *Server) printf(format string, a ...interface{}) {
|
|||||||
|
|
||||||
// errorf records an error in s's event log, unless s has been stopped.
|
// errorf records an error in s's event log, unless s has been stopped.
|
||||||
// REQUIRES s.mu is held.
|
// REQUIRES s.mu is held.
|
||||||
func (s *Server) errorf(format string, a ...interface{}) {
|
func (s *Server) errorf(format string, a ...any) {
|
||||||
if s.events != nil {
|
if s.events != nil {
|
||||||
s.events.Errorf(format, a...)
|
s.events.Errorf(format, a...)
|
||||||
}
|
}
|
||||||
@ -657,14 +686,14 @@ type ServiceRegistrar interface {
|
|||||||
// once the server has started serving.
|
// once the server has started serving.
|
||||||
// desc describes the service and its methods and handlers. impl is the
|
// desc describes the service and its methods and handlers. impl is the
|
||||||
// service implementation which is passed to the method handlers.
|
// service implementation which is passed to the method handlers.
|
||||||
RegisterService(desc *ServiceDesc, impl interface{})
|
RegisterService(desc *ServiceDesc, impl any)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterService registers a service and its implementation to the gRPC
|
// RegisterService registers a service and its implementation to the gRPC
|
||||||
// server. It is called from the IDL generated code. This must be called before
|
// server. It is called from the IDL generated code. This must be called before
|
||||||
// invoking Serve. If ss is non-nil (for legacy code), its type is checked to
|
// invoking Serve. If ss is non-nil (for legacy code), its type is checked to
|
||||||
// ensure it implements sd.HandlerType.
|
// ensure it implements sd.HandlerType.
|
||||||
func (s *Server) RegisterService(sd *ServiceDesc, ss interface{}) {
|
func (s *Server) RegisterService(sd *ServiceDesc, ss any) {
|
||||||
if ss != nil {
|
if ss != nil {
|
||||||
ht := reflect.TypeOf(sd.HandlerType).Elem()
|
ht := reflect.TypeOf(sd.HandlerType).Elem()
|
||||||
st := reflect.TypeOf(ss)
|
st := reflect.TypeOf(ss)
|
||||||
@ -675,7 +704,7 @@ func (s *Server) RegisterService(sd *ServiceDesc, ss interface{}) {
|
|||||||
s.register(sd, ss)
|
s.register(sd, ss)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) register(sd *ServiceDesc, ss interface{}) {
|
func (s *Server) register(sd *ServiceDesc, ss any) {
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
defer s.mu.Unlock()
|
defer s.mu.Unlock()
|
||||||
s.printf("RegisterService(%q)", sd.ServiceName)
|
s.printf("RegisterService(%q)", sd.ServiceName)
|
||||||
@ -716,7 +745,7 @@ type MethodInfo struct {
|
|||||||
type ServiceInfo struct {
|
type ServiceInfo struct {
|
||||||
Methods []MethodInfo
|
Methods []MethodInfo
|
||||||
// Metadata is the metadata specified in ServiceDesc when registering service.
|
// Metadata is the metadata specified in ServiceDesc when registering service.
|
||||||
Metadata interface{}
|
Metadata any
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetServiceInfo returns a map from service names to ServiceInfo.
|
// GetServiceInfo returns a map from service names to ServiceInfo.
|
||||||
@ -897,7 +926,7 @@ func (s *Server) drainServerTransports(addr string) {
|
|||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
conns := s.conns[addr]
|
conns := s.conns[addr]
|
||||||
for st := range conns {
|
for st := range conns {
|
||||||
st.Drain()
|
st.Drain("")
|
||||||
}
|
}
|
||||||
s.mu.Unlock()
|
s.mu.Unlock()
|
||||||
}
|
}
|
||||||
@ -917,6 +946,7 @@ func (s *Server) newHTTP2Transport(c net.Conn) transport.ServerTransport {
|
|||||||
InitialConnWindowSize: s.opts.initialConnWindowSize,
|
InitialConnWindowSize: s.opts.initialConnWindowSize,
|
||||||
WriteBufferSize: s.opts.writeBufferSize,
|
WriteBufferSize: s.opts.writeBufferSize,
|
||||||
ReadBufferSize: s.opts.readBufferSize,
|
ReadBufferSize: s.opts.readBufferSize,
|
||||||
|
SharedWriteBuffer: s.opts.sharedWriteBuffer,
|
||||||
ChannelzParentID: s.channelzID,
|
ChannelzParentID: s.channelzID,
|
||||||
MaxHeaderListSize: s.opts.maxHeaderListSize,
|
MaxHeaderListSize: s.opts.maxHeaderListSize,
|
||||||
HeaderTableSize: s.opts.headerTableSize,
|
HeaderTableSize: s.opts.headerTableSize,
|
||||||
@ -945,26 +975,26 @@ func (s *Server) serveStreams(st transport.ServerTransport) {
|
|||||||
defer st.Close(errors.New("finished serving streams for the server transport"))
|
defer st.Close(errors.New("finished serving streams for the server transport"))
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
var roundRobinCounter uint32
|
streamQuota := newHandlerQuota(s.opts.maxConcurrentStreams)
|
||||||
st.HandleStreams(func(stream *transport.Stream) {
|
st.HandleStreams(func(stream *transport.Stream) {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
if s.opts.numServerWorkers > 0 {
|
|
||||||
data := &serverWorkerData{st: st, wg: &wg, stream: stream}
|
streamQuota.acquire()
|
||||||
select {
|
f := func() {
|
||||||
case s.serverWorkerChannels[atomic.AddUint32(&roundRobinCounter, 1)%s.opts.numServerWorkers] <- data:
|
defer streamQuota.release()
|
||||||
default:
|
|
||||||
// If all stream workers are busy, fallback to the default code path.
|
|
||||||
go func() {
|
|
||||||
s.handleStream(st, stream, s.traceInfo(st, stream))
|
|
||||||
wg.Done()
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
s.handleStream(st, stream, s.traceInfo(st, stream))
|
s.handleStream(st, stream, s.traceInfo(st, stream))
|
||||||
}()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if s.opts.numServerWorkers > 0 {
|
||||||
|
select {
|
||||||
|
case s.serverWorkerChannel <- f:
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
// If all stream workers are busy, fallback to the default code path.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
go f()
|
||||||
}, func(ctx context.Context, method string) context.Context {
|
}, func(ctx context.Context, method string) context.Context {
|
||||||
if !EnableTracing {
|
if !EnableTracing {
|
||||||
return ctx
|
return ctx
|
||||||
@ -1053,7 +1083,7 @@ func (s *Server) addConn(addr string, st transport.ServerTransport) bool {
|
|||||||
if s.drain {
|
if s.drain {
|
||||||
// Transport added after we drained our existing conns: drain it
|
// Transport added after we drained our existing conns: drain it
|
||||||
// immediately.
|
// immediately.
|
||||||
st.Drain()
|
st.Drain("")
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.conns[addr] == nil {
|
if s.conns[addr] == nil {
|
||||||
@ -1103,7 +1133,7 @@ func (s *Server) incrCallsFailed() {
|
|||||||
atomic.AddInt64(&s.czData.callsFailed, 1)
|
atomic.AddInt64(&s.czData.callsFailed, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) sendResponse(t transport.ServerTransport, stream *transport.Stream, msg interface{}, cp Compressor, opts *transport.Options, comp encoding.Compressor) error {
|
func (s *Server) sendResponse(t transport.ServerTransport, stream *transport.Stream, msg any, cp Compressor, opts *transport.Options, comp encoding.Compressor) error {
|
||||||
data, err := encode(s.getCodec(stream.ContentSubtype()), msg)
|
data, err := encode(s.getCodec(stream.ContentSubtype()), msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
channelz.Error(logger, s.channelzID, "grpc: server failed to encode response: ", err)
|
channelz.Error(logger, s.channelzID, "grpc: server failed to encode response: ", err)
|
||||||
@ -1150,7 +1180,7 @@ func chainUnaryServerInterceptors(s *Server) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func chainUnaryInterceptors(interceptors []UnaryServerInterceptor) UnaryServerInterceptor {
|
func chainUnaryInterceptors(interceptors []UnaryServerInterceptor) UnaryServerInterceptor {
|
||||||
return func(ctx context.Context, req interface{}, info *UnaryServerInfo, handler UnaryHandler) (interface{}, error) {
|
return func(ctx context.Context, req any, info *UnaryServerInfo, handler UnaryHandler) (any, error) {
|
||||||
return interceptors[0](ctx, req, info, getChainUnaryHandler(interceptors, 0, info, handler))
|
return interceptors[0](ctx, req, info, getChainUnaryHandler(interceptors, 0, info, handler))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1159,7 +1189,7 @@ func getChainUnaryHandler(interceptors []UnaryServerInterceptor, curr int, info
|
|||||||
if curr == len(interceptors)-1 {
|
if curr == len(interceptors)-1 {
|
||||||
return finalHandler
|
return finalHandler
|
||||||
}
|
}
|
||||||
return func(ctx context.Context, req interface{}) (interface{}, error) {
|
return func(ctx context.Context, req any) (any, error) {
|
||||||
return interceptors[curr+1](ctx, req, info, getChainUnaryHandler(interceptors, curr+1, info, finalHandler))
|
return interceptors[curr+1](ctx, req, info, getChainUnaryHandler(interceptors, curr+1, info, finalHandler))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1196,7 +1226,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
|
|||||||
defer func() {
|
defer func() {
|
||||||
if trInfo != nil {
|
if trInfo != nil {
|
||||||
if err != nil && err != io.EOF {
|
if err != nil && err != io.EOF {
|
||||||
trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true)
|
trInfo.tr.LazyLog(&fmtStringer{"%v", []any{err}}, true)
|
||||||
trInfo.tr.SetError()
|
trInfo.tr.SetError()
|
||||||
}
|
}
|
||||||
trInfo.tr.Finish()
|
trInfo.tr.Finish()
|
||||||
@ -1252,7 +1282,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
|
|||||||
logEntry.PeerAddr = peer.Addr
|
logEntry.PeerAddr = peer.Addr
|
||||||
}
|
}
|
||||||
for _, binlog := range binlogs {
|
for _, binlog := range binlogs {
|
||||||
binlog.Log(logEntry)
|
binlog.Log(ctx, logEntry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1263,6 +1293,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
|
|||||||
var comp, decomp encoding.Compressor
|
var comp, decomp encoding.Compressor
|
||||||
var cp Compressor
|
var cp Compressor
|
||||||
var dc Decompressor
|
var dc Decompressor
|
||||||
|
var sendCompressorName string
|
||||||
|
|
||||||
// If dc is set and matches the stream's compression, use it. Otherwise, try
|
// If dc is set and matches the stream's compression, use it. Otherwise, try
|
||||||
// to find a matching registered compressor for decomp.
|
// to find a matching registered compressor for decomp.
|
||||||
@ -1283,12 +1314,18 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
|
|||||||
// NOTE: this needs to be ahead of all handling, https://github.com/grpc/grpc-go/issues/686.
|
// NOTE: this needs to be ahead of all handling, https://github.com/grpc/grpc-go/issues/686.
|
||||||
if s.opts.cp != nil {
|
if s.opts.cp != nil {
|
||||||
cp = s.opts.cp
|
cp = s.opts.cp
|
||||||
stream.SetSendCompress(cp.Type())
|
sendCompressorName = cp.Type()
|
||||||
} else if rc := stream.RecvCompress(); rc != "" && rc != encoding.Identity {
|
} else if rc := stream.RecvCompress(); rc != "" && rc != encoding.Identity {
|
||||||
// Legacy compressor not specified; attempt to respond with same encoding.
|
// Legacy compressor not specified; attempt to respond with same encoding.
|
||||||
comp = encoding.GetCompressor(rc)
|
comp = encoding.GetCompressor(rc)
|
||||||
if comp != nil {
|
if comp != nil {
|
||||||
stream.SetSendCompress(rc)
|
sendCompressorName = comp.Name()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if sendCompressorName != "" {
|
||||||
|
if err := stream.SetSendCompress(sendCompressorName); err != nil {
|
||||||
|
return status.Errorf(codes.Internal, "grpc: failed to set send compressor: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1296,7 +1333,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
|
|||||||
if len(shs) != 0 || len(binlogs) != 0 {
|
if len(shs) != 0 || len(binlogs) != 0 {
|
||||||
payInfo = &payloadInfo{}
|
payInfo = &payloadInfo{}
|
||||||
}
|
}
|
||||||
d, err := recvAndDecompress(&parser{r: stream}, stream, dc, s.opts.maxReceiveMessageSize, payInfo, decomp)
|
d, err := recvAndDecompress(&parser{r: stream, recvBufferPool: s.opts.recvBufferPool}, stream, dc, s.opts.maxReceiveMessageSize, payInfo, decomp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if e := t.WriteStatus(stream, status.Convert(err)); e != nil {
|
if e := t.WriteStatus(stream, status.Convert(err)); e != nil {
|
||||||
channelz.Warningf(logger, s.channelzID, "grpc: Server.processUnaryRPC failed to write status: %v", e)
|
channelz.Warningf(logger, s.channelzID, "grpc: Server.processUnaryRPC failed to write status: %v", e)
|
||||||
@ -1306,7 +1343,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
|
|||||||
if channelz.IsOn() {
|
if channelz.IsOn() {
|
||||||
t.IncrMsgRecv()
|
t.IncrMsgRecv()
|
||||||
}
|
}
|
||||||
df := func(v interface{}) error {
|
df := func(v any) error {
|
||||||
if err := s.getCodec(stream.ContentSubtype()).Unmarshal(d, v); err != nil {
|
if err := s.getCodec(stream.ContentSubtype()).Unmarshal(d, v); err != nil {
|
||||||
return status.Errorf(codes.Internal, "grpc: error unmarshalling request: %v", err)
|
return status.Errorf(codes.Internal, "grpc: error unmarshalling request: %v", err)
|
||||||
}
|
}
|
||||||
@ -1314,9 +1351,10 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
|
|||||||
sh.HandleRPC(stream.Context(), &stats.InPayload{
|
sh.HandleRPC(stream.Context(), &stats.InPayload{
|
||||||
RecvTime: time.Now(),
|
RecvTime: time.Now(),
|
||||||
Payload: v,
|
Payload: v,
|
||||||
WireLength: payInfo.wireLength + headerLen,
|
|
||||||
Data: d,
|
|
||||||
Length: len(d),
|
Length: len(d),
|
||||||
|
WireLength: payInfo.compressedLength + headerLen,
|
||||||
|
CompressedLength: payInfo.compressedLength,
|
||||||
|
Data: d,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if len(binlogs) != 0 {
|
if len(binlogs) != 0 {
|
||||||
@ -1324,7 +1362,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
|
|||||||
Message: d,
|
Message: d,
|
||||||
}
|
}
|
||||||
for _, binlog := range binlogs {
|
for _, binlog := range binlogs {
|
||||||
binlog.Log(cm)
|
binlog.Log(stream.Context(), cm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if trInfo != nil {
|
if trInfo != nil {
|
||||||
@ -1357,7 +1395,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
|
|||||||
Header: h,
|
Header: h,
|
||||||
}
|
}
|
||||||
for _, binlog := range binlogs {
|
for _, binlog := range binlogs {
|
||||||
binlog.Log(sh)
|
binlog.Log(stream.Context(), sh)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
st := &binarylog.ServerTrailer{
|
st := &binarylog.ServerTrailer{
|
||||||
@ -1365,7 +1403,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
|
|||||||
Err: appErr,
|
Err: appErr,
|
||||||
}
|
}
|
||||||
for _, binlog := range binlogs {
|
for _, binlog := range binlogs {
|
||||||
binlog.Log(st)
|
binlog.Log(stream.Context(), st)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return appErr
|
return appErr
|
||||||
@ -1375,6 +1413,11 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
|
|||||||
}
|
}
|
||||||
opts := &transport.Options{Last: true}
|
opts := &transport.Options{Last: true}
|
||||||
|
|
||||||
|
// Server handler could have set new compressor by calling SetSendCompressor.
|
||||||
|
// In case it is set, we need to use it for compressing outbound message.
|
||||||
|
if stream.SendCompress() != sendCompressorName {
|
||||||
|
comp = encoding.GetCompressor(stream.SendCompress())
|
||||||
|
}
|
||||||
if err := s.sendResponse(t, stream, reply, cp, opts, comp); err != nil {
|
if err := s.sendResponse(t, stream, reply, cp, opts, comp); err != nil {
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
// The entire stream is done (for unary RPC only).
|
// The entire stream is done (for unary RPC only).
|
||||||
@ -1402,8 +1445,8 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
|
|||||||
Err: appErr,
|
Err: appErr,
|
||||||
}
|
}
|
||||||
for _, binlog := range binlogs {
|
for _, binlog := range binlogs {
|
||||||
binlog.Log(sh)
|
binlog.Log(stream.Context(), sh)
|
||||||
binlog.Log(st)
|
binlog.Log(stream.Context(), st)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
@ -1417,8 +1460,8 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
|
|||||||
Message: reply,
|
Message: reply,
|
||||||
}
|
}
|
||||||
for _, binlog := range binlogs {
|
for _, binlog := range binlogs {
|
||||||
binlog.Log(sh)
|
binlog.Log(stream.Context(), sh)
|
||||||
binlog.Log(sm)
|
binlog.Log(stream.Context(), sm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if channelz.IsOn() {
|
if channelz.IsOn() {
|
||||||
@ -1430,17 +1473,16 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
|
|||||||
// TODO: Should we be logging if writing status failed here, like above?
|
// TODO: Should we be logging if writing status failed here, like above?
|
||||||
// Should the logging be in WriteStatus? Should we ignore the WriteStatus
|
// Should the logging be in WriteStatus? Should we ignore the WriteStatus
|
||||||
// error or allow the stats handler to see it?
|
// error or allow the stats handler to see it?
|
||||||
err = t.WriteStatus(stream, statusOK)
|
|
||||||
if len(binlogs) != 0 {
|
if len(binlogs) != 0 {
|
||||||
st := &binarylog.ServerTrailer{
|
st := &binarylog.ServerTrailer{
|
||||||
Trailer: stream.Trailer(),
|
Trailer: stream.Trailer(),
|
||||||
Err: appErr,
|
Err: appErr,
|
||||||
}
|
}
|
||||||
for _, binlog := range binlogs {
|
for _, binlog := range binlogs {
|
||||||
binlog.Log(st)
|
binlog.Log(stream.Context(), st)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err
|
return t.WriteStatus(stream, statusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
// chainStreamServerInterceptors chains all stream server interceptors into one.
|
// chainStreamServerInterceptors chains all stream server interceptors into one.
|
||||||
@ -1465,7 +1507,7 @@ func chainStreamServerInterceptors(s *Server) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func chainStreamInterceptors(interceptors []StreamServerInterceptor) StreamServerInterceptor {
|
func chainStreamInterceptors(interceptors []StreamServerInterceptor) StreamServerInterceptor {
|
||||||
return func(srv interface{}, ss ServerStream, info *StreamServerInfo, handler StreamHandler) error {
|
return func(srv any, ss ServerStream, info *StreamServerInfo, handler StreamHandler) error {
|
||||||
return interceptors[0](srv, ss, info, getChainStreamHandler(interceptors, 0, info, handler))
|
return interceptors[0](srv, ss, info, getChainStreamHandler(interceptors, 0, info, handler))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1474,7 +1516,7 @@ func getChainStreamHandler(interceptors []StreamServerInterceptor, curr int, inf
|
|||||||
if curr == len(interceptors)-1 {
|
if curr == len(interceptors)-1 {
|
||||||
return finalHandler
|
return finalHandler
|
||||||
}
|
}
|
||||||
return func(srv interface{}, stream ServerStream) error {
|
return func(srv any, stream ServerStream) error {
|
||||||
return interceptors[curr+1](srv, stream, info, getChainStreamHandler(interceptors, curr+1, info, finalHandler))
|
return interceptors[curr+1](srv, stream, info, getChainStreamHandler(interceptors, curr+1, info, finalHandler))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1501,7 +1543,7 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp
|
|||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
t: t,
|
t: t,
|
||||||
s: stream,
|
s: stream,
|
||||||
p: &parser{r: stream},
|
p: &parser{r: stream, recvBufferPool: s.opts.recvBufferPool},
|
||||||
codec: s.getCodec(stream.ContentSubtype()),
|
codec: s.getCodec(stream.ContentSubtype()),
|
||||||
maxReceiveMessageSize: s.opts.maxReceiveMessageSize,
|
maxReceiveMessageSize: s.opts.maxReceiveMessageSize,
|
||||||
maxSendMessageSize: s.opts.maxSendMessageSize,
|
maxSendMessageSize: s.opts.maxSendMessageSize,
|
||||||
@ -1515,7 +1557,7 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp
|
|||||||
if trInfo != nil {
|
if trInfo != nil {
|
||||||
ss.mu.Lock()
|
ss.mu.Lock()
|
||||||
if err != nil && err != io.EOF {
|
if err != nil && err != io.EOF {
|
||||||
ss.trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true)
|
ss.trInfo.tr.LazyLog(&fmtStringer{"%v", []any{err}}, true)
|
||||||
ss.trInfo.tr.SetError()
|
ss.trInfo.tr.SetError()
|
||||||
}
|
}
|
||||||
ss.trInfo.tr.Finish()
|
ss.trInfo.tr.Finish()
|
||||||
@ -1574,7 +1616,7 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp
|
|||||||
logEntry.PeerAddr = peer.Addr
|
logEntry.PeerAddr = peer.Addr
|
||||||
}
|
}
|
||||||
for _, binlog := range ss.binlogs {
|
for _, binlog := range ss.binlogs {
|
||||||
binlog.Log(logEntry)
|
binlog.Log(stream.Context(), logEntry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1597,12 +1639,18 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp
|
|||||||
// NOTE: this needs to be ahead of all handling, https://github.com/grpc/grpc-go/issues/686.
|
// NOTE: this needs to be ahead of all handling, https://github.com/grpc/grpc-go/issues/686.
|
||||||
if s.opts.cp != nil {
|
if s.opts.cp != nil {
|
||||||
ss.cp = s.opts.cp
|
ss.cp = s.opts.cp
|
||||||
stream.SetSendCompress(s.opts.cp.Type())
|
ss.sendCompressorName = s.opts.cp.Type()
|
||||||
} else if rc := stream.RecvCompress(); rc != "" && rc != encoding.Identity {
|
} else if rc := stream.RecvCompress(); rc != "" && rc != encoding.Identity {
|
||||||
// Legacy compressor not specified; attempt to respond with same encoding.
|
// Legacy compressor not specified; attempt to respond with same encoding.
|
||||||
ss.comp = encoding.GetCompressor(rc)
|
ss.comp = encoding.GetCompressor(rc)
|
||||||
if ss.comp != nil {
|
if ss.comp != nil {
|
||||||
stream.SetSendCompress(rc)
|
ss.sendCompressorName = rc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ss.sendCompressorName != "" {
|
||||||
|
if err := stream.SetSendCompress(ss.sendCompressorName); err != nil {
|
||||||
|
return status.Errorf(codes.Internal, "grpc: failed to set send compressor: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1612,7 +1660,7 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp
|
|||||||
trInfo.tr.LazyLog(&trInfo.firstLine, false)
|
trInfo.tr.LazyLog(&trInfo.firstLine, false)
|
||||||
}
|
}
|
||||||
var appErr error
|
var appErr error
|
||||||
var server interface{}
|
var server any
|
||||||
if info != nil {
|
if info != nil {
|
||||||
server = info.serviceImpl
|
server = info.serviceImpl
|
||||||
}
|
}
|
||||||
@ -1640,16 +1688,16 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp
|
|||||||
ss.trInfo.tr.SetError()
|
ss.trInfo.tr.SetError()
|
||||||
ss.mu.Unlock()
|
ss.mu.Unlock()
|
||||||
}
|
}
|
||||||
t.WriteStatus(ss.s, appStatus)
|
|
||||||
if len(ss.binlogs) != 0 {
|
if len(ss.binlogs) != 0 {
|
||||||
st := &binarylog.ServerTrailer{
|
st := &binarylog.ServerTrailer{
|
||||||
Trailer: ss.s.Trailer(),
|
Trailer: ss.s.Trailer(),
|
||||||
Err: appErr,
|
Err: appErr,
|
||||||
}
|
}
|
||||||
for _, binlog := range ss.binlogs {
|
for _, binlog := range ss.binlogs {
|
||||||
binlog.Log(st)
|
binlog.Log(stream.Context(), st)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
t.WriteStatus(ss.s, appStatus)
|
||||||
// TODO: Should we log an error from WriteStatus here and below?
|
// TODO: Should we log an error from WriteStatus here and below?
|
||||||
return appErr
|
return appErr
|
||||||
}
|
}
|
||||||
@ -1658,17 +1706,16 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp
|
|||||||
ss.trInfo.tr.LazyLog(stringer("OK"), false)
|
ss.trInfo.tr.LazyLog(stringer("OK"), false)
|
||||||
ss.mu.Unlock()
|
ss.mu.Unlock()
|
||||||
}
|
}
|
||||||
err = t.WriteStatus(ss.s, statusOK)
|
|
||||||
if len(ss.binlogs) != 0 {
|
if len(ss.binlogs) != 0 {
|
||||||
st := &binarylog.ServerTrailer{
|
st := &binarylog.ServerTrailer{
|
||||||
Trailer: ss.s.Trailer(),
|
Trailer: ss.s.Trailer(),
|
||||||
Err: appErr,
|
Err: appErr,
|
||||||
}
|
}
|
||||||
for _, binlog := range ss.binlogs {
|
for _, binlog := range ss.binlogs {
|
||||||
binlog.Log(st)
|
binlog.Log(stream.Context(), st)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err
|
return t.WriteStatus(ss.s, statusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Stream, trInfo *traceInfo) {
|
func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Stream, trInfo *traceInfo) {
|
||||||
@ -1679,13 +1726,13 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str
|
|||||||
pos := strings.LastIndex(sm, "/")
|
pos := strings.LastIndex(sm, "/")
|
||||||
if pos == -1 {
|
if pos == -1 {
|
||||||
if trInfo != nil {
|
if trInfo != nil {
|
||||||
trInfo.tr.LazyLog(&fmtStringer{"Malformed method name %q", []interface{}{sm}}, true)
|
trInfo.tr.LazyLog(&fmtStringer{"Malformed method name %q", []any{sm}}, true)
|
||||||
trInfo.tr.SetError()
|
trInfo.tr.SetError()
|
||||||
}
|
}
|
||||||
errDesc := fmt.Sprintf("malformed method name: %q", stream.Method())
|
errDesc := fmt.Sprintf("malformed method name: %q", stream.Method())
|
||||||
if err := t.WriteStatus(stream, status.New(codes.Unimplemented, errDesc)); err != nil {
|
if err := t.WriteStatus(stream, status.New(codes.Unimplemented, errDesc)); err != nil {
|
||||||
if trInfo != nil {
|
if trInfo != nil {
|
||||||
trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true)
|
trInfo.tr.LazyLog(&fmtStringer{"%v", []any{err}}, true)
|
||||||
trInfo.tr.SetError()
|
trInfo.tr.SetError()
|
||||||
}
|
}
|
||||||
channelz.Warningf(logger, s.channelzID, "grpc: Server.handleStream failed to write status: %v", err)
|
channelz.Warningf(logger, s.channelzID, "grpc: Server.handleStream failed to write status: %v", err)
|
||||||
@ -1726,7 +1773,7 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str
|
|||||||
}
|
}
|
||||||
if err := t.WriteStatus(stream, status.New(codes.Unimplemented, errDesc)); err != nil {
|
if err := t.WriteStatus(stream, status.New(codes.Unimplemented, errDesc)); err != nil {
|
||||||
if trInfo != nil {
|
if trInfo != nil {
|
||||||
trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true)
|
trInfo.tr.LazyLog(&fmtStringer{"%v", []any{err}}, true)
|
||||||
trInfo.tr.SetError()
|
trInfo.tr.SetError()
|
||||||
}
|
}
|
||||||
channelz.Warningf(logger, s.channelzID, "grpc: Server.handleStream failed to write status: %v", err)
|
channelz.Warningf(logger, s.channelzID, "grpc: Server.handleStream failed to write status: %v", err)
|
||||||
@ -1846,7 +1893,7 @@ func (s *Server) GracefulStop() {
|
|||||||
if !s.drain {
|
if !s.drain {
|
||||||
for _, conns := range s.conns {
|
for _, conns := range s.conns {
|
||||||
for st := range conns {
|
for st := range conns {
|
||||||
st.Drain()
|
st.Drain("graceful_stop")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.drain = true
|
s.drain = true
|
||||||
@ -1935,6 +1982,60 @@ func SendHeader(ctx context.Context, md metadata.MD) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetSendCompressor sets a compressor for outbound messages from the server.
|
||||||
|
// It must not be called after any event that causes headers to be sent
|
||||||
|
// (see ServerStream.SetHeader for the complete list). Provided compressor is
|
||||||
|
// used when below conditions are met:
|
||||||
|
//
|
||||||
|
// - compressor is registered via encoding.RegisterCompressor
|
||||||
|
// - compressor name must exist in the client advertised compressor names
|
||||||
|
// sent in grpc-accept-encoding header. Use ClientSupportedCompressors to
|
||||||
|
// get client supported compressor names.
|
||||||
|
//
|
||||||
|
// The context provided must be the context passed to the server's handler.
|
||||||
|
// It must be noted that compressor name encoding.Identity disables the
|
||||||
|
// outbound compression.
|
||||||
|
// By default, server messages will be sent using the same compressor with
|
||||||
|
// which request messages were sent.
|
||||||
|
//
|
||||||
|
// It is not safe to call SetSendCompressor concurrently with SendHeader and
|
||||||
|
// SendMsg.
|
||||||
|
//
|
||||||
|
// # Experimental
|
||||||
|
//
|
||||||
|
// Notice: This function is EXPERIMENTAL and may be changed or removed in a
|
||||||
|
// later release.
|
||||||
|
func SetSendCompressor(ctx context.Context, name string) error {
|
||||||
|
stream, ok := ServerTransportStreamFromContext(ctx).(*transport.Stream)
|
||||||
|
if !ok || stream == nil {
|
||||||
|
return fmt.Errorf("failed to fetch the stream from the given context")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validateSendCompressor(name, stream.ClientAdvertisedCompressors()); err != nil {
|
||||||
|
return fmt.Errorf("unable to set send compressor: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return stream.SetSendCompress(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClientSupportedCompressors returns compressor names advertised by the client
|
||||||
|
// via grpc-accept-encoding header.
|
||||||
|
//
|
||||||
|
// The context provided must be the context passed to the server's handler.
|
||||||
|
//
|
||||||
|
// # Experimental
|
||||||
|
//
|
||||||
|
// Notice: This function is EXPERIMENTAL and may be changed or removed in a
|
||||||
|
// later release.
|
||||||
|
func ClientSupportedCompressors(ctx context.Context) ([]string, error) {
|
||||||
|
stream, ok := ServerTransportStreamFromContext(ctx).(*transport.Stream)
|
||||||
|
if !ok || stream == nil {
|
||||||
|
return nil, fmt.Errorf("failed to fetch the stream from the given context %v", ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Split(stream.ClientAdvertisedCompressors(), ","), nil
|
||||||
|
}
|
||||||
|
|
||||||
// SetTrailer sets the trailer metadata that will be sent when an RPC returns.
|
// SetTrailer sets the trailer metadata that will be sent when an RPC returns.
|
||||||
// When called more than once, all the provided metadata will be merged.
|
// When called more than once, all the provided metadata will be merged.
|
||||||
//
|
//
|
||||||
@ -1969,3 +2070,53 @@ type channelzServer struct {
|
|||||||
func (c *channelzServer) ChannelzMetric() *channelz.ServerInternalMetric {
|
func (c *channelzServer) ChannelzMetric() *channelz.ServerInternalMetric {
|
||||||
return c.s.channelzMetric()
|
return c.s.channelzMetric()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// validateSendCompressor returns an error when given compressor name cannot be
|
||||||
|
// handled by the server or the client based on the advertised compressors.
|
||||||
|
func validateSendCompressor(name, clientCompressors string) error {
|
||||||
|
if name == encoding.Identity {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if !grpcutil.IsCompressorNameRegistered(name) {
|
||||||
|
return fmt.Errorf("compressor not registered %q", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range strings.Split(clientCompressors, ",") {
|
||||||
|
if c == name {
|
||||||
|
return nil // found match
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fmt.Errorf("client does not support compressor %q", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// atomicSemaphore implements a blocking, counting semaphore. acquire should be
|
||||||
|
// called synchronously; release may be called asynchronously.
|
||||||
|
type atomicSemaphore struct {
|
||||||
|
n atomic.Int64
|
||||||
|
wait chan struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *atomicSemaphore) acquire() {
|
||||||
|
if q.n.Add(-1) < 0 {
|
||||||
|
// We ran out of quota. Block until a release happens.
|
||||||
|
<-q.wait
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *atomicSemaphore) release() {
|
||||||
|
// N.B. the "<= 0" check below should allow for this to work with multiple
|
||||||
|
// concurrent calls to acquire, but also note that with synchronous calls to
|
||||||
|
// acquire, as our system does, n will never be less than -1. There are
|
||||||
|
// fairness issues (queuing) to consider if this was to be generalized.
|
||||||
|
if q.n.Add(1) <= 0 {
|
||||||
|
// An acquire was waiting on us. Unblock it.
|
||||||
|
q.wait <- struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newHandlerQuota(n uint32) *atomicSemaphore {
|
||||||
|
a := &atomicSemaphore{wait: make(chan struct{}, 1)}
|
||||||
|
a.n.Store(int64(n))
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
75
vendor/google.golang.org/grpc/service_config.go
generated
vendored
75
vendor/google.golang.org/grpc/service_config.go
generated
vendored
@ -23,8 +23,6 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
@ -106,8 +104,8 @@ type healthCheckConfig struct {
|
|||||||
|
|
||||||
type jsonRetryPolicy struct {
|
type jsonRetryPolicy struct {
|
||||||
MaxAttempts int
|
MaxAttempts int
|
||||||
InitialBackoff string
|
InitialBackoff internalserviceconfig.Duration
|
||||||
MaxBackoff string
|
MaxBackoff internalserviceconfig.Duration
|
||||||
BackoffMultiplier float64
|
BackoffMultiplier float64
|
||||||
RetryableStatusCodes []codes.Code
|
RetryableStatusCodes []codes.Code
|
||||||
}
|
}
|
||||||
@ -129,50 +127,6 @@ type retryThrottlingPolicy struct {
|
|||||||
TokenRatio float64
|
TokenRatio float64
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseDuration(s *string) (*time.Duration, error) {
|
|
||||||
if s == nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
if !strings.HasSuffix(*s, "s") {
|
|
||||||
return nil, fmt.Errorf("malformed duration %q", *s)
|
|
||||||
}
|
|
||||||
ss := strings.SplitN((*s)[:len(*s)-1], ".", 3)
|
|
||||||
if len(ss) > 2 {
|
|
||||||
return nil, fmt.Errorf("malformed duration %q", *s)
|
|
||||||
}
|
|
||||||
// hasDigits is set if either the whole or fractional part of the number is
|
|
||||||
// present, since both are optional but one is required.
|
|
||||||
hasDigits := false
|
|
||||||
var d time.Duration
|
|
||||||
if len(ss[0]) > 0 {
|
|
||||||
i, err := strconv.ParseInt(ss[0], 10, 32)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("malformed duration %q: %v", *s, err)
|
|
||||||
}
|
|
||||||
d = time.Duration(i) * time.Second
|
|
||||||
hasDigits = true
|
|
||||||
}
|
|
||||||
if len(ss) == 2 && len(ss[1]) > 0 {
|
|
||||||
if len(ss[1]) > 9 {
|
|
||||||
return nil, fmt.Errorf("malformed duration %q", *s)
|
|
||||||
}
|
|
||||||
f, err := strconv.ParseInt(ss[1], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("malformed duration %q: %v", *s, err)
|
|
||||||
}
|
|
||||||
for i := 9; i > len(ss[1]); i-- {
|
|
||||||
f *= 10
|
|
||||||
}
|
|
||||||
d += time.Duration(f)
|
|
||||||
hasDigits = true
|
|
||||||
}
|
|
||||||
if !hasDigits {
|
|
||||||
return nil, fmt.Errorf("malformed duration %q", *s)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &d, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type jsonName struct {
|
type jsonName struct {
|
||||||
Service string
|
Service string
|
||||||
Method string
|
Method string
|
||||||
@ -201,7 +155,7 @@ func (j jsonName) generatePath() (string, error) {
|
|||||||
type jsonMC struct {
|
type jsonMC struct {
|
||||||
Name *[]jsonName
|
Name *[]jsonName
|
||||||
WaitForReady *bool
|
WaitForReady *bool
|
||||||
Timeout *string
|
Timeout *internalserviceconfig.Duration
|
||||||
MaxRequestMessageBytes *int64
|
MaxRequestMessageBytes *int64
|
||||||
MaxResponseMessageBytes *int64
|
MaxResponseMessageBytes *int64
|
||||||
RetryPolicy *jsonRetryPolicy
|
RetryPolicy *jsonRetryPolicy
|
||||||
@ -252,15 +206,10 @@ func parseServiceConfig(js string) *serviceconfig.ParseResult {
|
|||||||
if m.Name == nil {
|
if m.Name == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
d, err := parseDuration(m.Timeout)
|
|
||||||
if err != nil {
|
|
||||||
logger.Warningf("grpc: unmarshaling service config %s: %v", js, err)
|
|
||||||
return &serviceconfig.ParseResult{Err: err}
|
|
||||||
}
|
|
||||||
|
|
||||||
mc := MethodConfig{
|
mc := MethodConfig{
|
||||||
WaitForReady: m.WaitForReady,
|
WaitForReady: m.WaitForReady,
|
||||||
Timeout: d,
|
Timeout: (*time.Duration)(m.Timeout),
|
||||||
}
|
}
|
||||||
if mc.RetryPolicy, err = convertRetryPolicy(m.RetryPolicy); err != nil {
|
if mc.RetryPolicy, err = convertRetryPolicy(m.RetryPolicy); err != nil {
|
||||||
logger.Warningf("grpc: unmarshaling service config %s: %v", js, err)
|
logger.Warningf("grpc: unmarshaling service config %s: %v", js, err)
|
||||||
@ -312,18 +261,10 @@ func convertRetryPolicy(jrp *jsonRetryPolicy) (p *internalserviceconfig.RetryPol
|
|||||||
if jrp == nil {
|
if jrp == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
ib, err := parseDuration(&jrp.InitialBackoff)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
mb, err := parseDuration(&jrp.MaxBackoff)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if jrp.MaxAttempts <= 1 ||
|
if jrp.MaxAttempts <= 1 ||
|
||||||
*ib <= 0 ||
|
jrp.InitialBackoff <= 0 ||
|
||||||
*mb <= 0 ||
|
jrp.MaxBackoff <= 0 ||
|
||||||
jrp.BackoffMultiplier <= 0 ||
|
jrp.BackoffMultiplier <= 0 ||
|
||||||
len(jrp.RetryableStatusCodes) == 0 {
|
len(jrp.RetryableStatusCodes) == 0 {
|
||||||
logger.Warningf("grpc: ignoring retry policy %v due to illegal configuration", jrp)
|
logger.Warningf("grpc: ignoring retry policy %v due to illegal configuration", jrp)
|
||||||
@ -332,8 +273,8 @@ func convertRetryPolicy(jrp *jsonRetryPolicy) (p *internalserviceconfig.RetryPol
|
|||||||
|
|
||||||
rp := &internalserviceconfig.RetryPolicy{
|
rp := &internalserviceconfig.RetryPolicy{
|
||||||
MaxAttempts: jrp.MaxAttempts,
|
MaxAttempts: jrp.MaxAttempts,
|
||||||
InitialBackoff: *ib,
|
InitialBackoff: time.Duration(jrp.InitialBackoff),
|
||||||
MaxBackoff: *mb,
|
MaxBackoff: time.Duration(jrp.MaxBackoff),
|
||||||
BackoffMultiplier: jrp.BackoffMultiplier,
|
BackoffMultiplier: jrp.BackoffMultiplier,
|
||||||
RetryableStatusCodes: make(map[codes.Code]bool),
|
RetryableStatusCodes: make(map[codes.Code]bool),
|
||||||
}
|
}
|
||||||
|
154
vendor/google.golang.org/grpc/shared_buffer_pool.go
generated
vendored
Normal file
154
vendor/google.golang.org/grpc/shared_buffer_pool.go
generated
vendored
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2023 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package grpc
|
||||||
|
|
||||||
|
import "sync"
|
||||||
|
|
||||||
|
// SharedBufferPool is a pool of buffers that can be shared, resulting in
|
||||||
|
// decreased memory allocation. Currently, in gRPC-go, it is only utilized
|
||||||
|
// for parsing incoming messages.
|
||||||
|
//
|
||||||
|
// # Experimental
|
||||||
|
//
|
||||||
|
// Notice: This API is EXPERIMENTAL and may be changed or removed in a
|
||||||
|
// later release.
|
||||||
|
type SharedBufferPool interface {
|
||||||
|
// Get returns a buffer with specified length from the pool.
|
||||||
|
//
|
||||||
|
// The returned byte slice may be not zero initialized.
|
||||||
|
Get(length int) []byte
|
||||||
|
|
||||||
|
// Put returns a buffer to the pool.
|
||||||
|
Put(*[]byte)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSharedBufferPool creates a simple SharedBufferPool with buckets
|
||||||
|
// of different sizes to optimize memory usage. This prevents the pool from
|
||||||
|
// wasting large amounts of memory, even when handling messages of varying sizes.
|
||||||
|
//
|
||||||
|
// # Experimental
|
||||||
|
//
|
||||||
|
// Notice: This API is EXPERIMENTAL and may be changed or removed in a
|
||||||
|
// later release.
|
||||||
|
func NewSharedBufferPool() SharedBufferPool {
|
||||||
|
return &simpleSharedBufferPool{
|
||||||
|
pools: [poolArraySize]simpleSharedBufferChildPool{
|
||||||
|
newBytesPool(level0PoolMaxSize),
|
||||||
|
newBytesPool(level1PoolMaxSize),
|
||||||
|
newBytesPool(level2PoolMaxSize),
|
||||||
|
newBytesPool(level3PoolMaxSize),
|
||||||
|
newBytesPool(level4PoolMaxSize),
|
||||||
|
newBytesPool(0),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// simpleSharedBufferPool is a simple implementation of SharedBufferPool.
|
||||||
|
type simpleSharedBufferPool struct {
|
||||||
|
pools [poolArraySize]simpleSharedBufferChildPool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *simpleSharedBufferPool) Get(size int) []byte {
|
||||||
|
return p.pools[p.poolIdx(size)].Get(size)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *simpleSharedBufferPool) Put(bs *[]byte) {
|
||||||
|
p.pools[p.poolIdx(cap(*bs))].Put(bs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *simpleSharedBufferPool) poolIdx(size int) int {
|
||||||
|
switch {
|
||||||
|
case size <= level0PoolMaxSize:
|
||||||
|
return level0PoolIdx
|
||||||
|
case size <= level1PoolMaxSize:
|
||||||
|
return level1PoolIdx
|
||||||
|
case size <= level2PoolMaxSize:
|
||||||
|
return level2PoolIdx
|
||||||
|
case size <= level3PoolMaxSize:
|
||||||
|
return level3PoolIdx
|
||||||
|
case size <= level4PoolMaxSize:
|
||||||
|
return level4PoolIdx
|
||||||
|
default:
|
||||||
|
return levelMaxPoolIdx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
level0PoolMaxSize = 16 // 16 B
|
||||||
|
level1PoolMaxSize = level0PoolMaxSize * 16 // 256 B
|
||||||
|
level2PoolMaxSize = level1PoolMaxSize * 16 // 4 KB
|
||||||
|
level3PoolMaxSize = level2PoolMaxSize * 16 // 64 KB
|
||||||
|
level4PoolMaxSize = level3PoolMaxSize * 16 // 1 MB
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
level0PoolIdx = iota
|
||||||
|
level1PoolIdx
|
||||||
|
level2PoolIdx
|
||||||
|
level3PoolIdx
|
||||||
|
level4PoolIdx
|
||||||
|
levelMaxPoolIdx
|
||||||
|
poolArraySize
|
||||||
|
)
|
||||||
|
|
||||||
|
type simpleSharedBufferChildPool interface {
|
||||||
|
Get(size int) []byte
|
||||||
|
Put(any)
|
||||||
|
}
|
||||||
|
|
||||||
|
type bufferPool struct {
|
||||||
|
sync.Pool
|
||||||
|
|
||||||
|
defaultSize int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *bufferPool) Get(size int) []byte {
|
||||||
|
bs := p.Pool.Get().(*[]byte)
|
||||||
|
|
||||||
|
if cap(*bs) < size {
|
||||||
|
p.Pool.Put(bs)
|
||||||
|
|
||||||
|
return make([]byte, size)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (*bs)[:size]
|
||||||
|
}
|
||||||
|
|
||||||
|
func newBytesPool(size int) simpleSharedBufferChildPool {
|
||||||
|
return &bufferPool{
|
||||||
|
Pool: sync.Pool{
|
||||||
|
New: func() any {
|
||||||
|
bs := make([]byte, size)
|
||||||
|
return &bs
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultSize: size,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// nopBufferPool is a buffer pool just makes new buffer without pooling.
|
||||||
|
type nopBufferPool struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (nopBufferPool) Get(length int) []byte {
|
||||||
|
return make([]byte, length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (nopBufferPool) Put(*[]byte) {
|
||||||
|
}
|
36
vendor/google.golang.org/grpc/stats/stats.go
generated
vendored
36
vendor/google.golang.org/grpc/stats/stats.go
generated
vendored
@ -59,18 +59,36 @@ func (s *Begin) IsClient() bool { return s.Client }
|
|||||||
|
|
||||||
func (s *Begin) isRPCStats() {}
|
func (s *Begin) isRPCStats() {}
|
||||||
|
|
||||||
|
// PickerUpdated indicates that the LB policy provided a new picker while the
|
||||||
|
// RPC was waiting for one.
|
||||||
|
type PickerUpdated struct{}
|
||||||
|
|
||||||
|
// IsClient indicates if the stats information is from client side. Only Client
|
||||||
|
// Side interfaces with a Picker, thus always returns true.
|
||||||
|
func (*PickerUpdated) IsClient() bool { return true }
|
||||||
|
|
||||||
|
func (*PickerUpdated) isRPCStats() {}
|
||||||
|
|
||||||
// InPayload contains the information for an incoming payload.
|
// InPayload contains the information for an incoming payload.
|
||||||
type InPayload struct {
|
type InPayload struct {
|
||||||
// Client is true if this InPayload is from client side.
|
// Client is true if this InPayload is from client side.
|
||||||
Client bool
|
Client bool
|
||||||
// Payload is the payload with original type.
|
// Payload is the payload with original type.
|
||||||
Payload interface{}
|
Payload any
|
||||||
// Data is the serialized message payload.
|
// Data is the serialized message payload.
|
||||||
Data []byte
|
Data []byte
|
||||||
// Length is the length of uncompressed data.
|
|
||||||
|
// Length is the size of the uncompressed payload data. Does not include any
|
||||||
|
// framing (gRPC or HTTP/2).
|
||||||
Length int
|
Length int
|
||||||
// WireLength is the length of data on wire (compressed, signed, encrypted).
|
// CompressedLength is the size of the compressed payload data. Does not
|
||||||
|
// include any framing (gRPC or HTTP/2). Same as Length if compression not
|
||||||
|
// enabled.
|
||||||
|
CompressedLength int
|
||||||
|
// WireLength is the size of the compressed payload data plus gRPC framing.
|
||||||
|
// Does not include HTTP/2 framing.
|
||||||
WireLength int
|
WireLength int
|
||||||
|
|
||||||
// RecvTime is the time when the payload is received.
|
// RecvTime is the time when the payload is received.
|
||||||
RecvTime time.Time
|
RecvTime time.Time
|
||||||
}
|
}
|
||||||
@ -126,12 +144,18 @@ type OutPayload struct {
|
|||||||
// Client is true if this OutPayload is from client side.
|
// Client is true if this OutPayload is from client side.
|
||||||
Client bool
|
Client bool
|
||||||
// Payload is the payload with original type.
|
// Payload is the payload with original type.
|
||||||
Payload interface{}
|
Payload any
|
||||||
// Data is the serialized message payload.
|
// Data is the serialized message payload.
|
||||||
Data []byte
|
Data []byte
|
||||||
// Length is the length of uncompressed data.
|
// Length is the size of the uncompressed payload data. Does not include any
|
||||||
|
// framing (gRPC or HTTP/2).
|
||||||
Length int
|
Length int
|
||||||
// WireLength is the length of data on wire (compressed, signed, encrypted).
|
// CompressedLength is the size of the compressed payload data. Does not
|
||||||
|
// include any framing (gRPC or HTTP/2). Same as Length if compression not
|
||||||
|
// enabled.
|
||||||
|
CompressedLength int
|
||||||
|
// WireLength is the size of the compressed payload data plus gRPC framing.
|
||||||
|
// Does not include HTTP/2 framing.
|
||||||
WireLength int
|
WireLength int
|
||||||
// SentTime is the time when the payload is sent.
|
// SentTime is the time when the payload is sent.
|
||||||
SentTime time.Time
|
SentTime time.Time
|
||||||
|
59
vendor/google.golang.org/grpc/status/status.go
generated
vendored
59
vendor/google.golang.org/grpc/status/status.go
generated
vendored
@ -50,7 +50,7 @@ func New(c codes.Code, msg string) *Status {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Newf returns New(c, fmt.Sprintf(format, a...)).
|
// Newf returns New(c, fmt.Sprintf(format, a...)).
|
||||||
func Newf(c codes.Code, format string, a ...interface{}) *Status {
|
func Newf(c codes.Code, format string, a ...any) *Status {
|
||||||
return New(c, fmt.Sprintf(format, a...))
|
return New(c, fmt.Sprintf(format, a...))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ func Error(c codes.Code, msg string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Errorf returns Error(c, fmt.Sprintf(format, a...)).
|
// Errorf returns Error(c, fmt.Sprintf(format, a...)).
|
||||||
func Errorf(c codes.Code, format string, a ...interface{}) error {
|
func Errorf(c codes.Code, format string, a ...any) error {
|
||||||
return Error(c, fmt.Sprintf(format, a...))
|
return Error(c, fmt.Sprintf(format, a...))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,9 +77,18 @@ func FromProto(s *spb.Status) *Status {
|
|||||||
// FromError returns a Status representation of err.
|
// FromError returns a Status representation of err.
|
||||||
//
|
//
|
||||||
// - If err was produced by this package or implements the method `GRPCStatus()
|
// - If err was produced by this package or implements the method `GRPCStatus()
|
||||||
// *Status`, the appropriate Status is returned.
|
// *Status` and `GRPCStatus()` does not return nil, or if err wraps a type
|
||||||
|
// satisfying this, the Status from `GRPCStatus()` is returned. For wrapped
|
||||||
|
// errors, the message returned contains the entire err.Error() text and not
|
||||||
|
// just the wrapped status. In that case, ok is true.
|
||||||
//
|
//
|
||||||
// - If err is nil, a Status is returned with codes.OK and no message.
|
// - If err is nil, a Status is returned with codes.OK and no message, and ok
|
||||||
|
// is true.
|
||||||
|
//
|
||||||
|
// - If err implements the method `GRPCStatus() *Status` and `GRPCStatus()`
|
||||||
|
// returns nil (which maps to Codes.OK), or if err wraps a type
|
||||||
|
// satisfying this, a Status is returned with codes.Unknown and err's
|
||||||
|
// Error() message, and ok is false.
|
||||||
//
|
//
|
||||||
// - Otherwise, err is an error not compatible with this package. In this
|
// - Otherwise, err is an error not compatible with this package. In this
|
||||||
// case, a Status is returned with codes.Unknown and err's Error() message,
|
// case, a Status is returned with codes.Unknown and err's Error() message,
|
||||||
@ -88,10 +97,31 @@ func FromError(err error) (s *Status, ok bool) {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
return nil, true
|
return nil, true
|
||||||
}
|
}
|
||||||
if se, ok := err.(interface {
|
type grpcstatus interface{ GRPCStatus() *Status }
|
||||||
GRPCStatus() *Status
|
if gs, ok := err.(grpcstatus); ok {
|
||||||
}); ok {
|
grpcStatus := gs.GRPCStatus()
|
||||||
return se.GRPCStatus(), true
|
if grpcStatus == nil {
|
||||||
|
// Error has status nil, which maps to codes.OK. There
|
||||||
|
// is no sensible behavior for this, so we turn it into
|
||||||
|
// an error with codes.Unknown and discard the existing
|
||||||
|
// status.
|
||||||
|
return New(codes.Unknown, err.Error()), false
|
||||||
|
}
|
||||||
|
return grpcStatus, true
|
||||||
|
}
|
||||||
|
var gs grpcstatus
|
||||||
|
if errors.As(err, &gs) {
|
||||||
|
grpcStatus := gs.GRPCStatus()
|
||||||
|
if grpcStatus == nil {
|
||||||
|
// Error wraps an error that has status nil, which maps
|
||||||
|
// to codes.OK. There is no sensible behavior for this,
|
||||||
|
// so we turn it into an error with codes.Unknown and
|
||||||
|
// discard the existing status.
|
||||||
|
return New(codes.Unknown, err.Error()), false
|
||||||
|
}
|
||||||
|
p := grpcStatus.Proto()
|
||||||
|
p.Message = err.Error()
|
||||||
|
return status.FromProto(p), true
|
||||||
}
|
}
|
||||||
return New(codes.Unknown, err.Error()), false
|
return New(codes.Unknown, err.Error()), false
|
||||||
}
|
}
|
||||||
@ -103,19 +133,16 @@ func Convert(err error) *Status {
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// Code returns the Code of the error if it is a Status error, codes.OK if err
|
// Code returns the Code of the error if it is a Status error or if it wraps a
|
||||||
// is nil, or codes.Unknown otherwise.
|
// Status error. If that is not the case, it returns codes.OK if err is nil, or
|
||||||
|
// codes.Unknown otherwise.
|
||||||
func Code(err error) codes.Code {
|
func Code(err error) codes.Code {
|
||||||
// Don't use FromError to avoid allocation of OK status.
|
// Don't use FromError to avoid allocation of OK status.
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return codes.OK
|
return codes.OK
|
||||||
}
|
}
|
||||||
if se, ok := err.(interface {
|
|
||||||
GRPCStatus() *Status
|
return Convert(err).Code()
|
||||||
}); ok {
|
|
||||||
return se.GRPCStatus().Code()
|
|
||||||
}
|
|
||||||
return codes.Unknown
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromContextError converts a context error or wrapped context error into a
|
// FromContextError converts a context error or wrapped context error into a
|
||||||
|
194
vendor/google.golang.org/grpc/stream.go
generated
vendored
194
vendor/google.golang.org/grpc/stream.go
generated
vendored
@ -31,6 +31,7 @@ import (
|
|||||||
"google.golang.org/grpc/balancer"
|
"google.golang.org/grpc/balancer"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/encoding"
|
"google.golang.org/grpc/encoding"
|
||||||
|
"google.golang.org/grpc/internal"
|
||||||
"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/channelz"
|
"google.golang.org/grpc/internal/channelz"
|
||||||
@ -54,7 +55,7 @@ import (
|
|||||||
// status package, or be one of the context errors. Otherwise, gRPC will use
|
// status package, or be one of the context errors. Otherwise, gRPC will use
|
||||||
// codes.Unknown as the status code and err.Error() as the status message of the
|
// codes.Unknown as the status code and err.Error() as the status message of the
|
||||||
// RPC.
|
// RPC.
|
||||||
type StreamHandler func(srv interface{}, stream ServerStream) error
|
type StreamHandler func(srv any, stream ServerStream) error
|
||||||
|
|
||||||
// StreamDesc represents a streaming RPC service's method specification. Used
|
// StreamDesc represents a streaming RPC service's method specification. Used
|
||||||
// on the server when registering services and on the client when initiating
|
// on the server when registering services and on the client when initiating
|
||||||
@ -79,9 +80,9 @@ type Stream interface {
|
|||||||
// Deprecated: See ClientStream and ServerStream documentation instead.
|
// Deprecated: See ClientStream and ServerStream documentation instead.
|
||||||
Context() context.Context
|
Context() context.Context
|
||||||
// Deprecated: See ClientStream and ServerStream documentation instead.
|
// Deprecated: See ClientStream and ServerStream documentation instead.
|
||||||
SendMsg(m interface{}) error
|
SendMsg(m any) error
|
||||||
// Deprecated: See ClientStream and ServerStream documentation instead.
|
// Deprecated: See ClientStream and ServerStream documentation instead.
|
||||||
RecvMsg(m interface{}) error
|
RecvMsg(m any) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClientStream defines the client-side behavior of a streaming RPC.
|
// ClientStream defines the client-side behavior of a streaming RPC.
|
||||||
@ -90,7 +91,9 @@ type Stream interface {
|
|||||||
// status package.
|
// status package.
|
||||||
type ClientStream interface {
|
type ClientStream interface {
|
||||||
// Header returns the header metadata received from the server if there
|
// Header returns the header metadata received from the server if there
|
||||||
// is any. It blocks if the metadata is not ready to read.
|
// is any. It blocks if the metadata is not ready to read. If the metadata
|
||||||
|
// is nil and the error is also nil, then the stream was terminated without
|
||||||
|
// headers, and the status can be discovered by calling RecvMsg.
|
||||||
Header() (metadata.MD, error)
|
Header() (metadata.MD, error)
|
||||||
// Trailer returns the trailer metadata from the server, if there is any.
|
// Trailer returns the trailer metadata from the server, if there is any.
|
||||||
// It must only be called after stream.CloseAndRecv has returned, or
|
// It must only be called after stream.CloseAndRecv has returned, or
|
||||||
@ -123,7 +126,10 @@ type ClientStream interface {
|
|||||||
// calling RecvMsg on the same stream at the same time, but it is not safe
|
// calling RecvMsg on the same stream at the same time, but it is not safe
|
||||||
// to call SendMsg on the same stream in different goroutines. It is also
|
// to call SendMsg on the same stream in different goroutines. It is also
|
||||||
// not safe to call CloseSend concurrently with SendMsg.
|
// not safe to call CloseSend concurrently with SendMsg.
|
||||||
SendMsg(m interface{}) error
|
//
|
||||||
|
// It is not safe to modify the message after calling SendMsg. Tracing
|
||||||
|
// libraries and stats handlers may use the message lazily.
|
||||||
|
SendMsg(m any) error
|
||||||
// RecvMsg blocks until it receives a message into m or the stream is
|
// RecvMsg blocks until it receives a message into m or the stream is
|
||||||
// done. It returns io.EOF when the stream completes successfully. On
|
// done. It returns io.EOF when the stream completes successfully. On
|
||||||
// any other error, the stream is aborted and the error contains the RPC
|
// any other error, the stream is aborted and the error contains the RPC
|
||||||
@ -132,7 +138,7 @@ type ClientStream interface {
|
|||||||
// It is safe to have a goroutine calling SendMsg and another goroutine
|
// It is safe to have a goroutine calling SendMsg and another goroutine
|
||||||
// calling RecvMsg on the same stream at the same time, but it is not
|
// calling RecvMsg on the same stream at the same time, but it is not
|
||||||
// safe to call RecvMsg on the same stream in different goroutines.
|
// safe to call RecvMsg on the same stream in different goroutines.
|
||||||
RecvMsg(m interface{}) error
|
RecvMsg(m any) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewStream creates a new Stream for the client side. This is typically
|
// NewStream creates a new Stream for the client side. This is typically
|
||||||
@ -168,10 +174,29 @@ 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 {
|
// Start tracking the RPC for idleness purposes. This is where a stream is
|
||||||
|
// created for both streaming and unary RPCs, and hence is a good place to
|
||||||
|
// track active RPC count.
|
||||||
|
if err := cc.idlenessMgr.OnCallBegin(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Add a calloption, to decrement the active call count, that gets executed
|
||||||
|
// when the RPC completes.
|
||||||
|
opts = append([]CallOption{OnFinish(func(error) { cc.idlenessMgr.OnCallEnd() })}, opts...)
|
||||||
|
|
||||||
|
if md, added, ok := metadata.FromOutgoingContextRaw(ctx); ok {
|
||||||
|
// validate md
|
||||||
if err := imetadata.Validate(md); err != nil {
|
if err := imetadata.Validate(md); err != nil {
|
||||||
return nil, status.Error(codes.Internal, err.Error())
|
return nil, status.Error(codes.Internal, err.Error())
|
||||||
}
|
}
|
||||||
|
// validate added
|
||||||
|
for _, kvs := range added {
|
||||||
|
for i := 0; i < len(kvs); i += 2 {
|
||||||
|
if err := imetadata.ValidatePair(kvs[i], kvs[i+1]); err != nil {
|
||||||
|
return nil, status.Error(codes.Internal, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if channelz.IsOn() {
|
if channelz.IsOn() {
|
||||||
cc.incrCallsStarted()
|
cc.incrCallsStarted()
|
||||||
@ -352,7 +377,7 @@ func newClientStreamWithParams(ctx context.Context, desc *StreamDesc, cc *Client
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, binlog := range cs.binlogs {
|
for _, binlog := range cs.binlogs {
|
||||||
binlog.Log(logEntry)
|
binlog.Log(cs.ctx, logEntry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,7 +441,7 @@ func (cs *clientStream) newAttemptLocked(isTransparent bool) (*csAttempt, error)
|
|||||||
ctx = trace.NewContext(ctx, trInfo.tr)
|
ctx = trace.NewContext(ctx, trInfo.tr)
|
||||||
}
|
}
|
||||||
|
|
||||||
if cs.cc.parsedTarget.URL.Scheme == "xds" {
|
if cs.cc.parsedTarget.URL.Scheme == internal.GRPCResolverSchemeExtraMetadata {
|
||||||
// Add extra metadata (metadata that will be added by transport) to context
|
// Add extra metadata (metadata that will be added by transport) to context
|
||||||
// so the balancer can see them.
|
// so the balancer can see them.
|
||||||
ctx = grpcutil.WithExtraMetadata(ctx, metadata.Pairs(
|
ctx = grpcutil.WithExtraMetadata(ctx, metadata.Pairs(
|
||||||
@ -460,7 +485,7 @@ func (a *csAttempt) newStream() error {
|
|||||||
// It is safe to overwrite the csAttempt's context here, since all state
|
// It is safe to overwrite the csAttempt's context here, since all state
|
||||||
// maintained in it are local to the attempt. When the attempt has to be
|
// maintained in it are local to the attempt. When the attempt has to be
|
||||||
// retried, a new instance of csAttempt will be created.
|
// retried, a new instance of csAttempt will be created.
|
||||||
if a.pickResult.Metatada != nil {
|
if a.pickResult.Metadata != nil {
|
||||||
// We currently do not have a function it the metadata package which
|
// We currently do not have a function it the metadata package which
|
||||||
// merges given metadata with existing metadata in a context. Existing
|
// merges given metadata with existing metadata in a context. Existing
|
||||||
// function `AppendToOutgoingContext()` takes a variadic argument of key
|
// function `AppendToOutgoingContext()` takes a variadic argument of key
|
||||||
@ -470,7 +495,7 @@ func (a *csAttempt) newStream() error {
|
|||||||
// in a form passable to AppendToOutgoingContext(), or create a version
|
// in a form passable to AppendToOutgoingContext(), or create a version
|
||||||
// of AppendToOutgoingContext() that accepts a metadata.MD.
|
// of AppendToOutgoingContext() that accepts a metadata.MD.
|
||||||
md, _ := metadata.FromOutgoingContext(a.ctx)
|
md, _ := metadata.FromOutgoingContext(a.ctx)
|
||||||
md = metadata.Join(md, a.pickResult.Metatada)
|
md = metadata.Join(md, a.pickResult.Metadata)
|
||||||
a.ctx = metadata.NewOutgoingContext(a.ctx, md)
|
a.ctx = metadata.NewOutgoingContext(a.ctx, md)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -490,7 +515,7 @@ func (a *csAttempt) newStream() error {
|
|||||||
return toRPCErr(nse.Err)
|
return toRPCErr(nse.Err)
|
||||||
}
|
}
|
||||||
a.s = s
|
a.s = s
|
||||||
a.p = &parser{r: s}
|
a.p = &parser{r: s, recvBufferPool: a.cs.cc.dopts.recvBufferPool}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -771,23 +796,24 @@ func (cs *clientStream) withRetry(op func(a *csAttempt) error, onSuccess func())
|
|||||||
|
|
||||||
func (cs *clientStream) Header() (metadata.MD, error) {
|
func (cs *clientStream) Header() (metadata.MD, error) {
|
||||||
var m metadata.MD
|
var m metadata.MD
|
||||||
noHeader := false
|
|
||||||
err := cs.withRetry(func(a *csAttempt) error {
|
err := cs.withRetry(func(a *csAttempt) error {
|
||||||
var err error
|
var err error
|
||||||
m, err = a.s.Header()
|
m, err = a.s.Header()
|
||||||
if err == transport.ErrNoHeaders {
|
|
||||||
noHeader = true
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return toRPCErr(err)
|
return toRPCErr(err)
|
||||||
}, cs.commitAttemptLocked)
|
}, cs.commitAttemptLocked)
|
||||||
|
|
||||||
if err != nil {
|
if m == nil && err == nil {
|
||||||
cs.finish(err)
|
// The stream ended with success. Finish the clientStream.
|
||||||
return nil, err
|
err = io.EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(cs.binlogs) != 0 && !cs.serverHeaderBinlogged && !noHeader {
|
if err != nil {
|
||||||
|
cs.finish(err)
|
||||||
|
// Do not return the error. The user should get it by calling Recv().
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(cs.binlogs) != 0 && !cs.serverHeaderBinlogged && m != nil {
|
||||||
// Only log if binary log is on and header has not been logged, and
|
// Only log if binary log is on and header has not been logged, and
|
||||||
// there is actually headers to log.
|
// there is actually headers to log.
|
||||||
logEntry := &binarylog.ServerHeader{
|
logEntry := &binarylog.ServerHeader{
|
||||||
@ -800,9 +826,10 @@ func (cs *clientStream) Header() (metadata.MD, error) {
|
|||||||
}
|
}
|
||||||
cs.serverHeaderBinlogged = true
|
cs.serverHeaderBinlogged = true
|
||||||
for _, binlog := range cs.binlogs {
|
for _, binlog := range cs.binlogs {
|
||||||
binlog.Log(logEntry)
|
binlog.Log(cs.ctx, logEntry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -843,7 +870,7 @@ func (cs *clientStream) bufferForRetryLocked(sz int, op func(a *csAttempt) error
|
|||||||
cs.buffer = append(cs.buffer, op)
|
cs.buffer = append(cs.buffer, op)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *clientStream) SendMsg(m interface{}) (err error) {
|
func (cs *clientStream) SendMsg(m any) (err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil && err != io.EOF {
|
if err != nil && err != io.EOF {
|
||||||
// Call finish on the client stream for errors generated by this SendMsg
|
// Call finish on the client stream for errors generated by this SendMsg
|
||||||
@ -881,13 +908,13 @@ func (cs *clientStream) SendMsg(m interface{}) (err error) {
|
|||||||
Message: data,
|
Message: data,
|
||||||
}
|
}
|
||||||
for _, binlog := range cs.binlogs {
|
for _, binlog := range cs.binlogs {
|
||||||
binlog.Log(cm)
|
binlog.Log(cs.ctx, cm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *clientStream) RecvMsg(m interface{}) error {
|
func (cs *clientStream) RecvMsg(m any) error {
|
||||||
if len(cs.binlogs) != 0 && !cs.serverHeaderBinlogged {
|
if len(cs.binlogs) != 0 && !cs.serverHeaderBinlogged {
|
||||||
// Call Header() to binary log header if it's not already logged.
|
// Call Header() to binary log header if it's not already logged.
|
||||||
cs.Header()
|
cs.Header()
|
||||||
@ -905,30 +932,12 @@ func (cs *clientStream) RecvMsg(m interface{}) error {
|
|||||||
Message: recvInfo.uncompressedBytes,
|
Message: recvInfo.uncompressedBytes,
|
||||||
}
|
}
|
||||||
for _, binlog := range cs.binlogs {
|
for _, binlog := range cs.binlogs {
|
||||||
binlog.Log(sm)
|
binlog.Log(cs.ctx, sm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err != nil || !cs.desc.ServerStreams {
|
if err != nil || !cs.desc.ServerStreams {
|
||||||
// err != nil or non-server-streaming indicates end of stream.
|
// err != nil or non-server-streaming indicates end of stream.
|
||||||
cs.finish(err)
|
cs.finish(err)
|
||||||
|
|
||||||
if len(cs.binlogs) != 0 {
|
|
||||||
// finish will not log Trailer. Log Trailer here.
|
|
||||||
logEntry := &binarylog.ServerTrailer{
|
|
||||||
OnClientSide: true,
|
|
||||||
Trailer: cs.Trailer(),
|
|
||||||
Err: err,
|
|
||||||
}
|
|
||||||
if logEntry.Err == io.EOF {
|
|
||||||
logEntry.Err = nil
|
|
||||||
}
|
|
||||||
if peer, ok := peer.FromContext(cs.Context()); ok {
|
|
||||||
logEntry.PeerAddr = peer.Addr
|
|
||||||
}
|
|
||||||
for _, binlog := range cs.binlogs {
|
|
||||||
binlog.Log(logEntry)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -953,7 +962,7 @@ func (cs *clientStream) CloseSend() error {
|
|||||||
OnClientSide: true,
|
OnClientSide: true,
|
||||||
}
|
}
|
||||||
for _, binlog := range cs.binlogs {
|
for _, binlog := range cs.binlogs {
|
||||||
binlog.Log(chc)
|
binlog.Log(cs.ctx, chc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// We never returned an error here for reasons.
|
// We never returned an error here for reasons.
|
||||||
@ -971,6 +980,9 @@ func (cs *clientStream) finish(err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
cs.finished = true
|
cs.finished = true
|
||||||
|
for _, onFinish := range cs.callInfo.onFinish {
|
||||||
|
onFinish(err)
|
||||||
|
}
|
||||||
cs.commitAttemptLocked()
|
cs.commitAttemptLocked()
|
||||||
if cs.attempt != nil {
|
if cs.attempt != nil {
|
||||||
cs.attempt.finish(err)
|
cs.attempt.finish(err)
|
||||||
@ -981,18 +993,30 @@ func (cs *clientStream) finish(err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cs.mu.Unlock()
|
cs.mu.Unlock()
|
||||||
// For binary logging. only log cancel in finish (could be caused by RPC ctx
|
// Only one of cancel or trailer needs to be logged.
|
||||||
// canceled or ClientConn closed). Trailer will be logged in RecvMsg.
|
if len(cs.binlogs) != 0 {
|
||||||
//
|
switch err {
|
||||||
// Only one of cancel or trailer needs to be logged. In the cases where
|
case errContextCanceled, errContextDeadline, ErrClientConnClosing:
|
||||||
// users don't call RecvMsg, users must have already canceled the RPC.
|
|
||||||
if len(cs.binlogs) != 0 && status.Code(err) == codes.Canceled {
|
|
||||||
c := &binarylog.Cancel{
|
c := &binarylog.Cancel{
|
||||||
OnClientSide: true,
|
OnClientSide: true,
|
||||||
}
|
}
|
||||||
for _, binlog := range cs.binlogs {
|
for _, binlog := range cs.binlogs {
|
||||||
binlog.Log(c)
|
binlog.Log(cs.ctx, c)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
logEntry := &binarylog.ServerTrailer{
|
||||||
|
OnClientSide: true,
|
||||||
|
Trailer: cs.Trailer(),
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
if peer, ok := peer.FromContext(cs.Context()); ok {
|
||||||
|
logEntry.PeerAddr = peer.Addr
|
||||||
|
}
|
||||||
|
for _, binlog := range cs.binlogs {
|
||||||
|
binlog.Log(cs.ctx, logEntry)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -1008,7 +1032,7 @@ func (cs *clientStream) finish(err error) {
|
|||||||
cs.cancel()
|
cs.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *csAttempt) sendMsg(m interface{}, hdr, payld, data []byte) error {
|
func (a *csAttempt) sendMsg(m any, hdr, payld, data []byte) error {
|
||||||
cs := a.cs
|
cs := a.cs
|
||||||
if a.trInfo != nil {
|
if a.trInfo != nil {
|
||||||
a.mu.Lock()
|
a.mu.Lock()
|
||||||
@ -1035,7 +1059,7 @@ func (a *csAttempt) sendMsg(m interface{}, hdr, payld, data []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *csAttempt) recvMsg(m interface{}, payInfo *payloadInfo) (err error) {
|
func (a *csAttempt) recvMsg(m any, payInfo *payloadInfo) (err error) {
|
||||||
cs := a.cs
|
cs := a.cs
|
||||||
if len(a.statsHandlers) != 0 && payInfo == nil {
|
if len(a.statsHandlers) != 0 && payInfo == nil {
|
||||||
payInfo = &payloadInfo{}
|
payInfo = &payloadInfo{}
|
||||||
@ -1082,7 +1106,8 @@ func (a *csAttempt) recvMsg(m interface{}, payInfo *payloadInfo) (err error) {
|
|||||||
Payload: m,
|
Payload: m,
|
||||||
// TODO truncate large payload.
|
// TODO truncate large payload.
|
||||||
Data: payInfo.uncompressedBytes,
|
Data: payInfo.uncompressedBytes,
|
||||||
WireLength: payInfo.wireLength + headerLen,
|
WireLength: payInfo.compressedLength + headerLen,
|
||||||
|
CompressedLength: payInfo.compressedLength,
|
||||||
Length: len(payInfo.uncompressedBytes),
|
Length: len(payInfo.uncompressedBytes),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -1249,17 +1274,22 @@ func newNonRetryClientStream(ctx context.Context, desc *StreamDesc, method strin
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
as.s = s
|
as.s = s
|
||||||
as.p = &parser{r: s}
|
as.p = &parser{r: s, recvBufferPool: ac.dopts.recvBufferPool}
|
||||||
ac.incrCallsStarted()
|
ac.incrCallsStarted()
|
||||||
if desc != unaryStreamDesc {
|
if desc != unaryStreamDesc {
|
||||||
// Listen on cc and stream contexts to cleanup when the user closes the
|
// Listen on stream context to cleanup when the stream context is
|
||||||
// ClientConn or cancels the stream context. In all other cases, an error
|
// canceled. Also listen for the addrConn's context in case the
|
||||||
// should already be injected into the recv buffer by the transport, which
|
// addrConn is closed or reconnects to a different address. In all
|
||||||
// the client will eventually receive, and then we will cancel the stream's
|
// other cases, an error should already be injected into the recv
|
||||||
// context in clientStream.finish.
|
// buffer by the transport, which the client will eventually receive,
|
||||||
|
// and then we will cancel the stream's context in
|
||||||
|
// addrConnStream.finish.
|
||||||
go func() {
|
go func() {
|
||||||
|
ac.mu.Lock()
|
||||||
|
acCtx := ac.ctx
|
||||||
|
ac.mu.Unlock()
|
||||||
select {
|
select {
|
||||||
case <-ac.ctx.Done():
|
case <-acCtx.Done():
|
||||||
as.finish(status.Error(codes.Canceled, "grpc: the SubConn is closing"))
|
as.finish(status.Error(codes.Canceled, "grpc: the SubConn is closing"))
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
as.finish(toRPCErr(ctx.Err()))
|
as.finish(toRPCErr(ctx.Err()))
|
||||||
@ -1322,7 +1352,7 @@ func (as *addrConnStream) Context() context.Context {
|
|||||||
return as.s.Context()
|
return as.s.Context()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (as *addrConnStream) SendMsg(m interface{}) (err error) {
|
func (as *addrConnStream) SendMsg(m any) (err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil && err != io.EOF {
|
if err != nil && err != io.EOF {
|
||||||
// Call finish on the client stream for errors generated by this SendMsg
|
// Call finish on the client stream for errors generated by this SendMsg
|
||||||
@ -1367,7 +1397,7 @@ func (as *addrConnStream) SendMsg(m interface{}) (err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (as *addrConnStream) RecvMsg(m interface{}) (err error) {
|
func (as *addrConnStream) RecvMsg(m any) (err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil || !as.desc.ServerStreams {
|
if err != nil || !as.desc.ServerStreams {
|
||||||
// err != nil or non-server-streaming indicates end of stream.
|
// err != nil or non-server-streaming indicates end of stream.
|
||||||
@ -1486,7 +1516,7 @@ type ServerStream interface {
|
|||||||
//
|
//
|
||||||
// It is not safe to modify the message after calling SendMsg. Tracing
|
// It is not safe to modify the message after calling SendMsg. Tracing
|
||||||
// libraries and stats handlers may use the message lazily.
|
// libraries and stats handlers may use the message lazily.
|
||||||
SendMsg(m interface{}) error
|
SendMsg(m any) error
|
||||||
// RecvMsg blocks until it receives a message into m or the stream is
|
// RecvMsg blocks until it receives a message into m or the stream is
|
||||||
// done. It returns io.EOF when the client has performed a CloseSend. On
|
// done. It returns io.EOF when the client has performed a CloseSend. On
|
||||||
// any non-EOF error, the stream is aborted and the error contains the
|
// any non-EOF error, the stream is aborted and the error contains the
|
||||||
@ -1495,7 +1525,7 @@ type ServerStream interface {
|
|||||||
// It is safe to have a goroutine calling SendMsg and another goroutine
|
// It is safe to have a goroutine calling SendMsg and another goroutine
|
||||||
// calling RecvMsg on the same stream at the same time, but it is not
|
// calling RecvMsg on the same stream at the same time, but it is not
|
||||||
// safe to call RecvMsg on the same stream in different goroutines.
|
// safe to call RecvMsg on the same stream in different goroutines.
|
||||||
RecvMsg(m interface{}) error
|
RecvMsg(m any) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// serverStream implements a server side Stream.
|
// serverStream implements a server side Stream.
|
||||||
@ -1511,6 +1541,8 @@ type serverStream struct {
|
|||||||
comp encoding.Compressor
|
comp encoding.Compressor
|
||||||
decomp encoding.Compressor
|
decomp encoding.Compressor
|
||||||
|
|
||||||
|
sendCompressorName string
|
||||||
|
|
||||||
maxReceiveMessageSize int
|
maxReceiveMessageSize int
|
||||||
maxSendMessageSize int
|
maxSendMessageSize int
|
||||||
trInfo *traceInfo
|
trInfo *traceInfo
|
||||||
@ -1558,7 +1590,7 @@ func (ss *serverStream) SendHeader(md metadata.MD) error {
|
|||||||
}
|
}
|
||||||
ss.serverHeaderBinlogged = true
|
ss.serverHeaderBinlogged = true
|
||||||
for _, binlog := range ss.binlogs {
|
for _, binlog := range ss.binlogs {
|
||||||
binlog.Log(sh)
|
binlog.Log(ss.ctx, sh)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
@ -1574,7 +1606,7 @@ func (ss *serverStream) SetTrailer(md metadata.MD) {
|
|||||||
ss.s.SetTrailer(md)
|
ss.s.SetTrailer(md)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *serverStream) SendMsg(m interface{}) (err error) {
|
func (ss *serverStream) SendMsg(m any) (err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if ss.trInfo != nil {
|
if ss.trInfo != nil {
|
||||||
ss.mu.Lock()
|
ss.mu.Lock()
|
||||||
@ -1582,7 +1614,7 @@ func (ss *serverStream) SendMsg(m interface{}) (err error) {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
ss.trInfo.tr.LazyLog(&payload{sent: true, msg: m}, true)
|
ss.trInfo.tr.LazyLog(&payload{sent: true, msg: m}, true)
|
||||||
} else {
|
} else {
|
||||||
ss.trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true)
|
ss.trInfo.tr.LazyLog(&fmtStringer{"%v", []any{err}}, true)
|
||||||
ss.trInfo.tr.SetError()
|
ss.trInfo.tr.SetError()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1603,6 +1635,13 @@ func (ss *serverStream) SendMsg(m interface{}) (err error) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
// Server handler could have set new compressor by calling SetSendCompressor.
|
||||||
|
// In case it is set, we need to use it for compressing outbound message.
|
||||||
|
if sendCompressorsName := ss.s.SendCompress(); sendCompressorsName != ss.sendCompressorName {
|
||||||
|
ss.comp = encoding.GetCompressor(sendCompressorsName)
|
||||||
|
ss.sendCompressorName = sendCompressorsName
|
||||||
|
}
|
||||||
|
|
||||||
// load hdr, payload, data
|
// load hdr, payload, data
|
||||||
hdr, payload, data, err := prepareMsg(m, ss.codec, ss.cp, ss.comp)
|
hdr, payload, data, err := prepareMsg(m, ss.codec, ss.cp, ss.comp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1624,14 +1663,14 @@ func (ss *serverStream) SendMsg(m interface{}) (err error) {
|
|||||||
}
|
}
|
||||||
ss.serverHeaderBinlogged = true
|
ss.serverHeaderBinlogged = true
|
||||||
for _, binlog := range ss.binlogs {
|
for _, binlog := range ss.binlogs {
|
||||||
binlog.Log(sh)
|
binlog.Log(ss.ctx, sh)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sm := &binarylog.ServerMessage{
|
sm := &binarylog.ServerMessage{
|
||||||
Message: data,
|
Message: data,
|
||||||
}
|
}
|
||||||
for _, binlog := range ss.binlogs {
|
for _, binlog := range ss.binlogs {
|
||||||
binlog.Log(sm)
|
binlog.Log(ss.ctx, sm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(ss.statsHandler) != 0 {
|
if len(ss.statsHandler) != 0 {
|
||||||
@ -1642,7 +1681,7 @@ func (ss *serverStream) SendMsg(m interface{}) (err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *serverStream) RecvMsg(m interface{}) (err error) {
|
func (ss *serverStream) RecvMsg(m any) (err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if ss.trInfo != nil {
|
if ss.trInfo != nil {
|
||||||
ss.mu.Lock()
|
ss.mu.Lock()
|
||||||
@ -1650,7 +1689,7 @@ func (ss *serverStream) RecvMsg(m interface{}) (err error) {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
ss.trInfo.tr.LazyLog(&payload{sent: false, msg: m}, true)
|
ss.trInfo.tr.LazyLog(&payload{sent: false, msg: m}, true)
|
||||||
} else if err != io.EOF {
|
} else if err != io.EOF {
|
||||||
ss.trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true)
|
ss.trInfo.tr.LazyLog(&fmtStringer{"%v", []any{err}}, true)
|
||||||
ss.trInfo.tr.SetError()
|
ss.trInfo.tr.SetError()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1679,7 +1718,7 @@ func (ss *serverStream) RecvMsg(m interface{}) (err error) {
|
|||||||
if len(ss.binlogs) != 0 {
|
if len(ss.binlogs) != 0 {
|
||||||
chc := &binarylog.ClientHalfClose{}
|
chc := &binarylog.ClientHalfClose{}
|
||||||
for _, binlog := range ss.binlogs {
|
for _, binlog := range ss.binlogs {
|
||||||
binlog.Log(chc)
|
binlog.Log(ss.ctx, chc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
@ -1696,8 +1735,9 @@ func (ss *serverStream) RecvMsg(m interface{}) (err error) {
|
|||||||
Payload: m,
|
Payload: m,
|
||||||
// TODO truncate large payload.
|
// TODO truncate large payload.
|
||||||
Data: payInfo.uncompressedBytes,
|
Data: payInfo.uncompressedBytes,
|
||||||
WireLength: payInfo.wireLength + headerLen,
|
|
||||||
Length: len(payInfo.uncompressedBytes),
|
Length: len(payInfo.uncompressedBytes),
|
||||||
|
WireLength: payInfo.compressedLength + headerLen,
|
||||||
|
CompressedLength: payInfo.compressedLength,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1706,7 +1746,7 @@ func (ss *serverStream) RecvMsg(m interface{}) (err error) {
|
|||||||
Message: payInfo.uncompressedBytes,
|
Message: payInfo.uncompressedBytes,
|
||||||
}
|
}
|
||||||
for _, binlog := range ss.binlogs {
|
for _, binlog := range ss.binlogs {
|
||||||
binlog.Log(cm)
|
binlog.Log(ss.ctx, cm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -1721,7 +1761,7 @@ func MethodFromServerStream(stream ServerStream) (string, bool) {
|
|||||||
// prepareMsg returns the hdr, payload and data
|
// prepareMsg returns the hdr, payload and data
|
||||||
// using the compressors passed or using the
|
// using the compressors passed or using the
|
||||||
// passed preparedmsg
|
// passed preparedmsg
|
||||||
func prepareMsg(m interface{}, codec baseCodec, cp Compressor, comp encoding.Compressor) (hdr, payload, data []byte, err error) {
|
func prepareMsg(m any, codec baseCodec, cp Compressor, comp encoding.Compressor) (hdr, payload, data []byte, err error) {
|
||||||
if preparedMsg, ok := m.(*PreparedMsg); ok {
|
if preparedMsg, ok := m.(*PreparedMsg); ok {
|
||||||
return preparedMsg.hdr, preparedMsg.payload, preparedMsg.encodedData, nil
|
return preparedMsg.hdr, preparedMsg.payload, preparedMsg.encodedData, nil
|
||||||
}
|
}
|
||||||
|
4
vendor/google.golang.org/grpc/trace.go
generated
vendored
4
vendor/google.golang.org/grpc/trace.go
generated
vendored
@ -98,7 +98,7 @@ func truncate(x string, l int) string {
|
|||||||
// payload represents an RPC request or response payload.
|
// payload represents an RPC request or response payload.
|
||||||
type payload struct {
|
type payload struct {
|
||||||
sent bool // whether this is an outgoing payload
|
sent bool // whether this is an outgoing payload
|
||||||
msg interface{} // e.g. a proto.Message
|
msg any // e.g. a proto.Message
|
||||||
// TODO(dsymonds): add stringifying info to codec, and limit how much we hold here?
|
// TODO(dsymonds): add stringifying info to codec, and limit how much we hold here?
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +111,7 @@ func (p payload) String() string {
|
|||||||
|
|
||||||
type fmtStringer struct {
|
type fmtStringer struct {
|
||||||
format string
|
format string
|
||||||
a []interface{}
|
a []any
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *fmtStringer) String() string {
|
func (f *fmtStringer) String() string {
|
||||||
|
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.53.0"
|
const Version = "1.58.3"
|
||||||
|
22
vendor/google.golang.org/grpc/vet.sh
generated
vendored
22
vendor/google.golang.org/grpc/vet.sh
generated
vendored
@ -41,16 +41,8 @@ if [[ "$1" = "-install" ]]; then
|
|||||||
github.com/client9/misspell/cmd/misspell
|
github.com/client9/misspell/cmd/misspell
|
||||||
popd
|
popd
|
||||||
if [[ -z "${VET_SKIP_PROTO}" ]]; then
|
if [[ -z "${VET_SKIP_PROTO}" ]]; then
|
||||||
if [[ "${TRAVIS}" = "true" ]]; then
|
if [[ "${GITHUB_ACTIONS}" = "true" ]]; then
|
||||||
PROTOBUF_VERSION=3.14.0
|
PROTOBUF_VERSION=22.0 # a.k.a v4.22.0 in pb.go files.
|
||||||
PROTOC_FILENAME=protoc-${PROTOBUF_VERSION}-linux-x86_64.zip
|
|
||||||
pushd /home/travis
|
|
||||||
wget https://github.com/google/protobuf/releases/download/v${PROTOBUF_VERSION}/${PROTOC_FILENAME}
|
|
||||||
unzip ${PROTOC_FILENAME}
|
|
||||||
bin/protoc --version
|
|
||||||
popd
|
|
||||||
elif [[ "${GITHUB_ACTIONS}" = "true" ]]; then
|
|
||||||
PROTOBUF_VERSION=3.14.0
|
|
||||||
PROTOC_FILENAME=protoc-${PROTOBUF_VERSION}-linux-x86_64.zip
|
PROTOC_FILENAME=protoc-${PROTOBUF_VERSION}-linux-x86_64.zip
|
||||||
pushd /home/runner/go
|
pushd /home/runner/go
|
||||||
wget https://github.com/google/protobuf/releases/download/v${PROTOBUF_VERSION}/${PROTOC_FILENAME}
|
wget https://github.com/google/protobuf/releases/download/v${PROTOBUF_VERSION}/${PROTOC_FILENAME}
|
||||||
@ -68,8 +60,7 @@ fi
|
|||||||
|
|
||||||
# - Check that generated proto files are up to date.
|
# - Check that generated proto files are up to date.
|
||||||
if [[ -z "${VET_SKIP_PROTO}" ]]; then
|
if [[ -z "${VET_SKIP_PROTO}" ]]; then
|
||||||
PATH="/home/travis/bin:${PATH}" make proto && \
|
make proto && git status --porcelain 2>&1 | fail_on_output || \
|
||||||
git status --porcelain 2>&1 | fail_on_output || \
|
|
||||||
(git status; git --no-pager diff; exit 1)
|
(git status; git --no-pager diff; exit 1)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -93,6 +84,9 @@ not git grep -l 'x/net/context' -- "*.go"
|
|||||||
# thread safety.
|
# thread safety.
|
||||||
git grep -l '"math/rand"' -- "*.go" 2>&1 | not grep -v '^examples\|^stress\|grpcrand\|^benchmark\|wrr_test'
|
git grep -l '"math/rand"' -- "*.go" 2>&1 | not grep -v '^examples\|^stress\|grpcrand\|^benchmark\|wrr_test'
|
||||||
|
|
||||||
|
# - Do not use "interface{}"; use "any" instead.
|
||||||
|
git grep -l 'interface{}' -- "*.go" 2>&1 | not grep -v '\.pb\.go\|protoc-gen-go-grpc'
|
||||||
|
|
||||||
# - Do not call grpclog directly. Use grpclog.Component instead.
|
# - Do not call grpclog directly. Use grpclog.Component instead.
|
||||||
git grep -l -e 'grpclog.I' --or -e 'grpclog.W' --or -e 'grpclog.E' --or -e 'grpclog.F' --or -e 'grpclog.V' -- "*.go" | not grep -v '^grpclog/component.go\|^internal/grpctest/tlogger_test.go'
|
git grep -l -e 'grpclog.I' --or -e 'grpclog.W' --or -e 'grpclog.E' --or -e 'grpclog.F' --or -e 'grpclog.V' -- "*.go" | not grep -v '^grpclog/component.go\|^internal/grpctest/tlogger_test.go'
|
||||||
|
|
||||||
@ -115,7 +109,7 @@ for MOD_FILE in $(find . -name 'go.mod'); do
|
|||||||
goimports -l . 2>&1 | not grep -vE "\.pb\.go"
|
goimports -l . 2>&1 | not grep -vE "\.pb\.go"
|
||||||
golint ./... 2>&1 | not grep -vE "/grpc_testing_not_regenerate/.*\.pb\.go:"
|
golint ./... 2>&1 | not grep -vE "/grpc_testing_not_regenerate/.*\.pb\.go:"
|
||||||
|
|
||||||
go mod tidy -compat=1.17
|
go mod tidy -compat=1.19
|
||||||
git status --porcelain 2>&1 | fail_on_output || \
|
git status --porcelain 2>&1 | fail_on_output || \
|
||||||
(git status; git --no-pager diff; exit 1)
|
(git status; git --no-pager diff; exit 1)
|
||||||
popd
|
popd
|
||||||
@ -177,8 +171,6 @@ proto.RegisteredExtension is deprecated
|
|||||||
proto.RegisteredExtensions is deprecated
|
proto.RegisteredExtensions is deprecated
|
||||||
proto.RegisterMapType is deprecated
|
proto.RegisterMapType is deprecated
|
||||||
proto.Unmarshaler is deprecated
|
proto.Unmarshaler is deprecated
|
||||||
resolver.Backend
|
|
||||||
resolver.GRPCLB
|
|
||||||
Target is deprecated: Use the Target field in the BuildOptions instead.
|
Target is deprecated: Use the Target field in the BuildOptions instead.
|
||||||
xxx_messageInfo_
|
xxx_messageInfo_
|
||||||
' "${SC_OUT}"
|
' "${SC_OUT}"
|
||||||
|
13
vendor/modules.txt
vendored
13
vendor/modules.txt
vendored
@ -846,14 +846,18 @@ google.golang.org/appengine/internal/log
|
|||||||
google.golang.org/appengine/internal/remote_api
|
google.golang.org/appengine/internal/remote_api
|
||||||
google.golang.org/appengine/internal/urlfetch
|
google.golang.org/appengine/internal/urlfetch
|
||||||
google.golang.org/appengine/urlfetch
|
google.golang.org/appengine/urlfetch
|
||||||
# google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4
|
# google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98
|
||||||
|
## explicit; go 1.19
|
||||||
|
google.golang.org/genproto/protobuf/field_mask
|
||||||
|
# google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98
|
||||||
## explicit; go 1.19
|
## explicit; go 1.19
|
||||||
google.golang.org/genproto/googleapis/api/httpbody
|
google.golang.org/genproto/googleapis/api/httpbody
|
||||||
|
# google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98
|
||||||
|
## explicit; go 1.19
|
||||||
google.golang.org/genproto/googleapis/rpc/errdetails
|
google.golang.org/genproto/googleapis/rpc/errdetails
|
||||||
google.golang.org/genproto/googleapis/rpc/status
|
google.golang.org/genproto/googleapis/rpc/status
|
||||||
google.golang.org/genproto/protobuf/field_mask
|
# google.golang.org/grpc v1.58.3
|
||||||
# google.golang.org/grpc v1.53.0
|
## explicit; go 1.19
|
||||||
## explicit; go 1.17
|
|
||||||
google.golang.org/grpc
|
google.golang.org/grpc
|
||||||
google.golang.org/grpc/attributes
|
google.golang.org/grpc/attributes
|
||||||
google.golang.org/grpc/backoff
|
google.golang.org/grpc/backoff
|
||||||
@ -886,6 +890,7 @@ google.golang.org/grpc/internal/grpclog
|
|||||||
google.golang.org/grpc/internal/grpcrand
|
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/idle
|
||||||
google.golang.org/grpc/internal/metadata
|
google.golang.org/grpc/internal/metadata
|
||||||
google.golang.org/grpc/internal/pretty
|
google.golang.org/grpc/internal/pretty
|
||||||
google.golang.org/grpc/internal/resolver
|
google.golang.org/grpc/internal/resolver
|
||||||
|
Loading…
x
Reference in New Issue
Block a user