upgrade to latest dependencies (#879)

bumping golang.org/x/net 66e838c...e2310ae:
  > e2310ae go.mod: update golang.org/x dependencies
  > 77708f7 quic: skip tests which depend on unimplemented UDP functions on Plan 9
  > 9617c63 http2: avoid Transport hang with Connection: close and AllowHTTP
bumping golang.org/x/sys 673e0f9...faed7ec:
  > faed7ec unix: add PthreadChdir and PthreadFchdir on darwin
  > c892bb7 unix: fix MmapPtr test failing on OpenBSD
  > a0ef40a unix: fix MremapPtr test failing on NetBSD
  > daa2394 unix: add unsafe mmap, munmap, mremap
  > 7670087 windows: add GetAce Windows API
  > 348425a windows/svc: do not pass theService to windows.RegisterServiceCtrlHandlerEx
bumping golang.org/x/tools bc6931d...33be3ef:
  > 33be3ef go.mod: update golang.org/x dependencies
  > 0e7ccc0 gopls/internal/golang: provide version info for stdlib in pkgdoc
  > fcf5463 gopls/internal/server: add counters to inform v0.17.0
  > 70a59b2 gopls/doc: respond to Hana's review of CL 583316
  > 799a471 gopls/doc: document all of gopls' features
  > 2e239ad gopls/internal/golang: provide version info for stdlib fields
  > bc15dd8 gopls/internal/analysis/fillstruct: use package name (not path) in UI
  > 72edac2 internal/typeparams: fix crash in interface hover with empty type set
  > c0ae6bb gopls/internal/golang: splitlines: s/parameter/arguments/ in CallExpr
  > 5cc2d0b gopls/internal/golang: splitlines: remove workaround for golang/go# 68202
  > 6916077 gopls/internal/golang: don't panic when findKeyword fails
  > 8fa4173 gopls/internal/server: conditionally prompt for telemetry
  > b9a361a gopls/internal/golang: provide version info for stdlib methods
  > dd9d554 go/ast/astutil: PathEnclosingInterval: add missing FuncType nodes
  > 3db1ddb gopls/internal/golang: provide available version info in stdlib hover
  > 008ed2c gopls/internal/golang/completion: fix package clause completion suffix
  > b297f5a gopls/internal/golang: s/return values/results/
  > b5bfa9c gopls/internal/fuzzy: move the fuzzy package to gopls
  > 02912f7 gopls/internal/cache: lift package caching to forEachPackage
  > e7f294d gopls/matcher: don't give bonus to case insensitive match
  > 480a22d gopls/completion: don't take address of interfaces for "%p" values
  > 3151270 gopls/internal: add code action "extract declarations to new file"
  > 850c7c3 gopls: skip failing tests on wasm/wasip1
  > dc34122 gopls/internal/golang: fix hovering from the builtin file
  > 1028e30 gopls/internal/settings: remove fieldalignment analyzer
  > 5fefc65 go/analysis/passes/stringintconv: do not generate empty edits
  > 1e6c1e2 gopls/internal/golang: strip @v1.2.3 suffix from pkgdoc URLs
  > 7de8d0a gopls/internal/analysis/simplifyrange: reenable on range-over-func
  > c9675c2 internal/refactor/inline: avoid unnecessary import renames
  > f06ed92 gopls/internal/settings: define InlayHints enum
  > 833def6 gopls/internal/settings: move CodeActionKind values from protocol
  > 47bd819 gopls/internal/server: fix CSS typo
  > df4e862 gopls/internal/settings: minor cleanups
  > 4a26477 internal/refactor/inline: allow duplicable type conversions
  > db513b0 go/ssa: wait for shared functions to finish building
  > 8a45e6c go/analysis/passes/asmdecl: define register-ABI result registers for loong64
  > dfdfa49 go/types/objectpath: support Signature.RecvTypeParams
  > 2d104ec gopls/doc/generate: treat LinksInHover as an enum
  > b994346 gopls/doc/assets: create dummy submodule for image files
  > 18e694b gopls/doc/release: finalize v0.16.0 release notes
  > 99779e9 gopls/internal/settings: move CodeLensSource from protocol
  > 9bf0e21 gopls/internal/test/integration/misc: skip asm test unless a{rm,md}64
  > f2d2ebe go/analysis/passes/buildtag: retire Go 1.15 support
  > 1239d04 gopls/internal/golang:  Hover: use internal pkg doc viewer
  > 6ece8fb gopls/internal/golang: improve ergonomics of "Browse documentation"
  > 693d7fe gopls/internal/settings: simplify SetOptions
  > 977f6f7 go/packages: move getSizesForArgs back
  > 6a8bc5f gopls/internal/lsp/source: ignore lambdas in call hierarchy
  > b5dbe8b gopls/internal/golang: s/View/Browse/ for browser-based features
  > 2ca6abe gopls: expand on documentation about version support changes
  > b59dd37 go/analysis: document interpretation of multiple diagnostics
  > 4419f4f go/analysis/passes/stringintconv: offer fix of fmt.Sprint(x)
  > a69d9a2 internal/analysisinternal: AddImport helper for inserting imports
  > db99e8a gopls/internal/test/integration/misc: skip ASM assertions on risc64
  > a852b25 gopls/doc/release: update gopls release notes for language support
  > 03d7125 gopls/doc/emacs.md: use more precise before-save terminology
  > e4b0a18 internal/checker: run despite all errors
  > f45db9b internal/protocol/command: regenerate commands to fix build
  > 568dea1 gopls: update x/telemetry dependency
  > 82912d2 internal/imports: fix starvation in external candidate search
  > 3e94830 internal/imports: optimize package path filtering
  > dddd55d go/ssa: fixing Named type substitution
  > 46928a5 gopls: fix StmtToInsertVarBefore for switch stmts
  > 318adf2 gopls/internal/protocol/command/gen: omit unnecessary MarshalArgs calls
  > bffeaaa gopls/internal/golang: s/Show/View/ for web-based reports
  > a9021a5 go/ssa: export Defer.DeferStack field
  > ae52477 cmd/deadcode: fix nil panic in Edge.Site.Pos
  > 82be0b4 gopls/internal/server: return a non-nil slice for empty token result
  > 413a491 gopls/internal/golang: factor the 3 web reports
  > f41a407 gopls/internal/golang: Web, an abstraction of server.web
  > f5a26d2 gopls/internal/server: simplify FreeSymbols plumbing
  > 0341917 gopls/internal/cache: stop module cache refresh on view shutdown
  > 8f4c6b0 gopls/internal/test/integration/misc: fix build
  > 15d13c3 gopls/internal/golang: add "Show assembly of f" code action
  > a35b054 gopls/internal/test/integration: style tweaks to CodeAction
  > fc82f4e gopls/internal/protocol/command: use gopls.foo form everywhere
  > c24ae10 gopls/internal/cmd: cleanup progress handling
  > 6e3b208 gopls/internal/test: add test case for parameter rename match import
  > 5e0f1d8 gopls/internal/server: fix regression in organize imports code action
  > 1c73966 internal/imports: add a warning not to remove the fixImports seam
  > d9366dd internal/imports: restore fixImports extension point
  > 8bf61b8 gopls/internal/cache: fix module resolver cache refreshing
  > 7522327 gopls/rename: Fix spurious package name conflicts.
  > 5e43887 internal/stdlib: generate from api/next/*.txt (go1.23) too
bumping golang.org/x/mod c0bdc7b...d58be1c:
  > d58be1c sumdb/tlog: set the hash of the empty tree according to RFC 6962
  > 232e49f Revert "module: add COM0 and LPT0 to badWindowsNames"
bumping knative.dev/pkg 3f6a546...b4e5f07:
  > b4e5f07 Bump google.golang.org/grpc from 1.64.0 to 1.65.0 (# 3073)
  > fe204d0 Bump golang.org/x/net from 0.26.0 to 0.27.0 (# 3072)
  > 9dc5206 Bump golang.org/x/tools from 0.22.0 to 0.23.0 (# 3074)
  > 7ecd548 Update community files (# 3071)
bumping golang.org/x/term 5f0bb72...c976cb1:
  > c976cb1 go.mod: update golang.org/x dependencies
bumping knative.dev/hack 0914314...b979959:
  > b979959 Update community files (# 387)

Signed-off-by: Knative Automation <automation@knative.team>
This commit is contained in:
Knative Automation 2024-07-10 14:59:20 -04:00 committed by GitHub
parent 9cad6d8071
commit 2a0991fd01
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
50 changed files with 828 additions and 533 deletions

18
go.mod
View File

@ -10,8 +10,8 @@ require (
k8s.io/client-go v0.29.2 k8s.io/client-go v0.29.2
k8s.io/code-generator v0.29.2 k8s.io/code-generator v0.29.2
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00
knative.dev/hack v0.0.0-20240607132042-09143140a254 knative.dev/hack v0.0.0-20240704013904-b9799599afcf
knative.dev/pkg v0.0.0-20240626134149-3f6a546ac3a4 knative.dev/pkg v0.0.0-20240708181110-b4e5f07a2c37
) )
require ( require (
@ -20,7 +20,7 @@ require (
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
github.com/blendle/zapdriver v1.3.1 // indirect github.com/blendle/zapdriver v1.3.1 // indirect
github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect
@ -56,20 +56,20 @@ require (
github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/pflag v1.0.5 // indirect
go.opencensus.io v0.24.0 // indirect go.opencensus.io v0.24.0 // indirect
go.uber.org/multierr v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect
golang.org/x/mod v0.18.0 // indirect golang.org/x/mod v0.19.0 // indirect
golang.org/x/net v0.26.0 // indirect golang.org/x/net v0.27.0 // indirect
golang.org/x/oauth2 v0.21.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect
golang.org/x/sync v0.7.0 // indirect golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.21.0 // indirect golang.org/x/sys v0.22.0 // indirect
golang.org/x/term v0.21.0 // indirect golang.org/x/term v0.22.0 // indirect
golang.org/x/text v0.16.0 // indirect golang.org/x/text v0.16.0 // indirect
golang.org/x/time v0.5.0 // indirect golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.22.0 // indirect golang.org/x/tools v0.23.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/api v0.183.0 // indirect google.golang.org/api v0.183.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect
google.golang.org/grpc v1.64.0 // indirect google.golang.org/grpc v1.65.0 // indirect
google.golang.org/protobuf v1.34.1 // indirect google.golang.org/protobuf v1.34.1 // 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

40
go.sum
View File

@ -55,8 +55,8 @@ github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMr
github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
@ -107,8 +107,8 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= 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/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.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4=
github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
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=
@ -353,8 +353,8 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -389,8 +389,8 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -454,12 +454,12 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -517,8 +517,8 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -598,8 +598,8 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
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=
@ -661,10 +661,10 @@ k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/A
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA=
k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ= k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ=
k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
knative.dev/hack v0.0.0-20240607132042-09143140a254 h1:1YFnu3U6dWZg0oxm6GU8kEdA9A+BvSWKJO7sg3N0kq8= knative.dev/hack v0.0.0-20240704013904-b9799599afcf h1:n92FmZRywgtHso7pFAku7CW0qvRAs1hXtMQqO0R6eiE=
knative.dev/hack v0.0.0-20240607132042-09143140a254/go.mod h1:yk2OjGDsbEnQjfxdm0/HJKS2WqTLEFg/N6nUs6Rqx3Q= knative.dev/hack v0.0.0-20240704013904-b9799599afcf/go.mod h1:yk2OjGDsbEnQjfxdm0/HJKS2WqTLEFg/N6nUs6Rqx3Q=
knative.dev/pkg v0.0.0-20240626134149-3f6a546ac3a4 h1:slPKf3UKdBFZlz+hFy+KXzTgY9yOePLzRuEhKzgc5a4= knative.dev/pkg v0.0.0-20240708181110-b4e5f07a2c37 h1:YJopww8+M2C6vdiKzHAP98917VxEZhkBJ66P3ilhU/4=
knative.dev/pkg v0.0.0-20240626134149-3f6a546ac3a4/go.mod h1:Wikg4u73T6vk9TctrxZt60VXzqmGEQIx0iKfk1+9o4c= knative.dev/pkg v0.0.0-20240708181110-b4e5f07a2c37/go.mod h1:QB3K3LuhP+jeEZmiEPapv2bfeSSLVSMWuTAw2SSM7uw=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=

View File

@ -70,3 +70,5 @@ benchstat <(go test -benchtime 500ms -count 15 -bench 'Sum64$')
- [VictoriaMetrics](https://github.com/VictoriaMetrics/VictoriaMetrics) - [VictoriaMetrics](https://github.com/VictoriaMetrics/VictoriaMetrics)
- [FreeCache](https://github.com/coocood/freecache) - [FreeCache](https://github.com/coocood/freecache)
- [FastCache](https://github.com/VictoriaMetrics/fastcache) - [FastCache](https://github.com/VictoriaMetrics/fastcache)
- [Ristretto](https://github.com/dgraph-io/ristretto)
- [Badger](https://github.com/dgraph-io/badger)

View File

@ -19,10 +19,13 @@ const (
// Store the primes in an array as well. // Store the primes in an array as well.
// //
// The consts are used when possible in Go code to avoid MOVs but we need a // The consts are used when possible in Go code to avoid MOVs but we need a
// contiguous array of the assembly code. // contiguous array for the assembly code.
var primes = [...]uint64{prime1, prime2, prime3, prime4, prime5} var primes = [...]uint64{prime1, prime2, prime3, prime4, prime5}
// Digest implements hash.Hash64. // Digest implements hash.Hash64.
//
// Note that a zero-valued Digest is not ready to receive writes.
// Call Reset or create a Digest using New before calling other methods.
type Digest struct { type Digest struct {
v1 uint64 v1 uint64
v2 uint64 v2 uint64
@ -33,19 +36,31 @@ type Digest struct {
n int // how much of mem is used n int // how much of mem is used
} }
// New creates a new Digest that computes the 64-bit xxHash algorithm. // New creates a new Digest with a zero seed.
func New() *Digest { func New() *Digest {
return NewWithSeed(0)
}
// NewWithSeed creates a new Digest with the given seed.
func NewWithSeed(seed uint64) *Digest {
var d Digest var d Digest
d.Reset() d.ResetWithSeed(seed)
return &d return &d
} }
// Reset clears the Digest's state so that it can be reused. // Reset clears the Digest's state so that it can be reused.
// It uses a seed value of zero.
func (d *Digest) Reset() { func (d *Digest) Reset() {
d.v1 = primes[0] + prime2 d.ResetWithSeed(0)
d.v2 = prime2 }
d.v3 = 0
d.v4 = -primes[0] // ResetWithSeed clears the Digest's state so that it can be reused.
// It uses the given seed to initialize the state.
func (d *Digest) ResetWithSeed(seed uint64) {
d.v1 = seed + prime1 + prime2
d.v2 = seed + prime2
d.v3 = seed
d.v4 = seed - prime1
d.total = 0 d.total = 0
d.n = 0 d.n = 0
} }

View File

@ -6,7 +6,7 @@
package xxhash package xxhash
// Sum64 computes the 64-bit xxHash digest of b. // Sum64 computes the 64-bit xxHash digest of b with a zero seed.
// //
//go:noescape //go:noescape
func Sum64(b []byte) uint64 func Sum64(b []byte) uint64

View File

@ -3,7 +3,7 @@
package xxhash package xxhash
// Sum64 computes the 64-bit xxHash digest of b. // Sum64 computes the 64-bit xxHash digest of b with a zero seed.
func Sum64(b []byte) uint64 { func Sum64(b []byte) uint64 {
// A simpler version would be // A simpler version would be
// d := New() // d := New()

View File

@ -5,7 +5,7 @@
package xxhash package xxhash
// Sum64String computes the 64-bit xxHash digest of s. // Sum64String computes the 64-bit xxHash digest of s with a zero seed.
func Sum64String(s string) uint64 { func Sum64String(s string) uint64 {
return Sum64([]byte(s)) return Sum64([]byte(s))
} }

View File

@ -33,7 +33,7 @@ import (
// //
// See https://github.com/golang/go/issues/42739 for discussion. // See https://github.com/golang/go/issues/42739 for discussion.
// Sum64String computes the 64-bit xxHash digest of s. // Sum64String computes the 64-bit xxHash digest of s with a zero seed.
// It may be faster than Sum64([]byte(s)) by avoiding a copy. // It may be faster than Sum64([]byte(s)) by avoiding a copy.
func Sum64String(s string) uint64 { func Sum64String(s string) uint64 {
b := *(*[]byte)(unsafe.Pointer(&sliceHeader{s, len(s)})) b := *(*[]byte)(unsafe.Pointer(&sliceHeader{s, len(s)}))

View File

@ -506,7 +506,6 @@ var badWindowsNames = []string{
"PRN", "PRN",
"AUX", "AUX",
"NUL", "NUL",
"COM0",
"COM1", "COM1",
"COM2", "COM2",
"COM3", "COM3",
@ -516,7 +515,6 @@ var badWindowsNames = []string{
"COM7", "COM7",
"COM8", "COM8",
"COM9", "COM9",
"LPT0",
"LPT1", "LPT1",
"LPT2", "LPT2",
"LPT3", "LPT3",

View File

@ -827,10 +827,6 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro
cc.henc.SetMaxDynamicTableSizeLimit(t.maxEncoderHeaderTableSize()) cc.henc.SetMaxDynamicTableSizeLimit(t.maxEncoderHeaderTableSize())
cc.peerMaxHeaderTableSize = initialHeaderTableSize cc.peerMaxHeaderTableSize = initialHeaderTableSize
if t.AllowHTTP {
cc.nextStreamID = 3
}
if cs, ok := c.(connectionStater); ok { if cs, ok := c.(connectionStater); ok {
state := cs.ConnectionState() state := cs.ConnectionState()
cc.tlsState = &state cc.tlsState = &state

View File

@ -50,3 +50,8 @@ func (m *mremapMmapper) Mremap(oldData []byte, newLength int, flags int) (data [
func Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) { func Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) {
return mapper.Mremap(oldData, newLength, flags) return mapper.Mremap(oldData, newLength, flags)
} }
func MremapPtr(oldAddr unsafe.Pointer, oldSize uintptr, newAddr unsafe.Pointer, newSize uintptr, flags int) (ret unsafe.Pointer, err error) {
xaddr, err := mapper.mremap(uintptr(oldAddr), oldSize, newSize, flags, uintptr(newAddr))
return unsafe.Pointer(xaddr), err
}

View File

@ -542,6 +542,18 @@ func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) {
} }
} }
//sys pthread_chdir_np(path string) (err error)
func PthreadChdir(path string) (err error) {
return pthread_chdir_np(path)
}
//sys pthread_fchdir_np(fd int) (err error)
func PthreadFchdir(fd int) (err error) {
return pthread_fchdir_np(fd)
}
//sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) //sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error)
//sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error) //sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error)

View File

@ -154,6 +154,15 @@ func Munmap(b []byte) (err error) {
return mapper.Munmap(b) return mapper.Munmap(b)
} }
func MmapPtr(fd int, offset int64, addr unsafe.Pointer, length uintptr, prot int, flags int) (ret unsafe.Pointer, err error) {
xaddr, err := mapper.mmap(uintptr(addr), length, prot, flags, fd, offset)
return unsafe.Pointer(xaddr), err
}
func MunmapPtr(addr unsafe.Pointer, length uintptr) (err error) {
return mapper.munmap(uintptr(addr), length)
}
func Read(fd int, p []byte) (n int, err error) { func Read(fd int, p []byte) (n int, err error) {
n, err = read(fd, p) n, err = read(fd, p)
if raceenabled { if raceenabled {

View File

@ -760,6 +760,39 @@ var libc_sysctl_trampoline_addr uintptr
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func pthread_chdir_np(path string) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
if err != nil {
return
}
_, _, e1 := syscall_syscall(libc_pthread_chdir_np_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
var libc_pthread_chdir_np_trampoline_addr uintptr
//go:cgo_import_dynamic libc_pthread_chdir_np pthread_chdir_np "/usr/lib/libSystem.B.dylib"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func pthread_fchdir_np(fd int) (err error) {
_, _, e1 := syscall_syscall(libc_pthread_fchdir_np_trampoline_addr, uintptr(fd), 0, 0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
var libc_pthread_fchdir_np_trampoline_addr uintptr
//go:cgo_import_dynamic libc_pthread_fchdir_np pthread_fchdir_np "/usr/lib/libSystem.B.dylib"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) { func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) {
_, _, e1 := syscall_syscall6(libc_sendfile_trampoline_addr, uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags)) _, _, e1 := syscall_syscall6(libc_sendfile_trampoline_addr, uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags))
if e1 != 0 { if e1 != 0 {

View File

@ -228,6 +228,16 @@ TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8 GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8
DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB) DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
TEXT libc_pthread_chdir_np_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_pthread_chdir_np(SB)
GLOBL ·libc_pthread_chdir_np_trampoline_addr(SB), RODATA, $8
DATA ·libc_pthread_chdir_np_trampoline_addr(SB)/8, $libc_pthread_chdir_np_trampoline<>(SB)
TEXT libc_pthread_fchdir_np_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_pthread_fchdir_np(SB)
GLOBL ·libc_pthread_fchdir_np_trampoline_addr(SB), RODATA, $8
DATA ·libc_pthread_fchdir_np_trampoline_addr(SB)/8, $libc_pthread_fchdir_np_trampoline<>(SB)
TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0 TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_sendfile(SB) JMP libc_sendfile(SB)
GLOBL ·libc_sendfile_trampoline_addr(SB), RODATA, $8 GLOBL ·libc_sendfile_trampoline_addr(SB), RODATA, $8

View File

@ -760,6 +760,39 @@ var libc_sysctl_trampoline_addr uintptr
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func pthread_chdir_np(path string) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
if err != nil {
return
}
_, _, e1 := syscall_syscall(libc_pthread_chdir_np_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
var libc_pthread_chdir_np_trampoline_addr uintptr
//go:cgo_import_dynamic libc_pthread_chdir_np pthread_chdir_np "/usr/lib/libSystem.B.dylib"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func pthread_fchdir_np(fd int) (err error) {
_, _, e1 := syscall_syscall(libc_pthread_fchdir_np_trampoline_addr, uintptr(fd), 0, 0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
var libc_pthread_fchdir_np_trampoline_addr uintptr
//go:cgo_import_dynamic libc_pthread_fchdir_np pthread_fchdir_np "/usr/lib/libSystem.B.dylib"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) { func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) {
_, _, e1 := syscall_syscall6(libc_sendfile_trampoline_addr, uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags)) _, _, e1 := syscall_syscall6(libc_sendfile_trampoline_addr, uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags))
if e1 != 0 { if e1 != 0 {

View File

@ -228,6 +228,16 @@ TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8 GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8
DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB) DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
TEXT libc_pthread_chdir_np_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_pthread_chdir_np(SB)
GLOBL ·libc_pthread_chdir_np_trampoline_addr(SB), RODATA, $8
DATA ·libc_pthread_chdir_np_trampoline_addr(SB)/8, $libc_pthread_chdir_np_trampoline<>(SB)
TEXT libc_pthread_fchdir_np_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_pthread_fchdir_np(SB)
GLOBL ·libc_pthread_fchdir_np_trampoline_addr(SB), RODATA, $8
DATA ·libc_pthread_fchdir_np_trampoline_addr(SB)/8, $libc_pthread_fchdir_np_trampoline<>(SB)
TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0 TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_sendfile(SB) JMP libc_sendfile(SB)
GLOBL ·libc_sendfile_trampoline_addr(SB), RODATA, $8 GLOBL ·libc_sendfile_trampoline_addr(SB), RODATA, $8

View File

@ -894,7 +894,7 @@ type ACL struct {
aclRevision byte aclRevision byte
sbz1 byte sbz1 byte
aclSize uint16 aclSize uint16
aceCount uint16 AceCount uint16
sbz2 uint16 sbz2 uint16
} }
@ -1087,6 +1087,27 @@ type EXPLICIT_ACCESS struct {
Trustee TRUSTEE Trustee TRUSTEE
} }
// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header
type ACE_HEADER struct {
AceType uint8
AceFlags uint8
AceSize uint16
}
// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_allowed_ace
type ACCESS_ALLOWED_ACE struct {
Header ACE_HEADER
Mask ACCESS_MASK
SidStart uint32
}
const (
// Constants for AceType
// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header
ACCESS_ALLOWED_ACE_TYPE = 0
ACCESS_DENIED_ACE_TYPE = 1
)
// This type is the union inside of TRUSTEE and must be created using one of the TrusteeValueFrom* functions. // This type is the union inside of TRUSTEE and must be created using one of the TrusteeValueFrom* functions.
type TrusteeValue uintptr type TrusteeValue uintptr
@ -1158,6 +1179,7 @@ type OBJECTS_AND_NAME struct {
//sys makeSelfRelativeSD(absoluteSD *SECURITY_DESCRIPTOR, selfRelativeSD *SECURITY_DESCRIPTOR, selfRelativeSDSize *uint32) (err error) = advapi32.MakeSelfRelativeSD //sys makeSelfRelativeSD(absoluteSD *SECURITY_DESCRIPTOR, selfRelativeSD *SECURITY_DESCRIPTOR, selfRelativeSDSize *uint32) (err error) = advapi32.MakeSelfRelativeSD
//sys setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCESS, oldACL *ACL, newACL **ACL) (ret error) = advapi32.SetEntriesInAclW //sys setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCESS, oldACL *ACL, newACL **ACL) (ret error) = advapi32.SetEntriesInAclW
//sys GetAce(acl *ACL, aceIndex uint32, pAce **ACCESS_ALLOWED_ACE) (ret error) = advapi32.GetAce
// Control returns the security descriptor control bits. // Control returns the security descriptor control bits.
func (sd *SECURITY_DESCRIPTOR) Control() (control SECURITY_DESCRIPTOR_CONTROL, revision uint32, err error) { func (sd *SECURITY_DESCRIPTOR) Control() (control SECURITY_DESCRIPTOR_CONTROL, revision uint32, err error) {

View File

@ -91,6 +91,7 @@ var (
procEnumServicesStatusExW = modadvapi32.NewProc("EnumServicesStatusExW") procEnumServicesStatusExW = modadvapi32.NewProc("EnumServicesStatusExW")
procEqualSid = modadvapi32.NewProc("EqualSid") procEqualSid = modadvapi32.NewProc("EqualSid")
procFreeSid = modadvapi32.NewProc("FreeSid") procFreeSid = modadvapi32.NewProc("FreeSid")
procGetAce = modadvapi32.NewProc("GetAce")
procGetLengthSid = modadvapi32.NewProc("GetLengthSid") procGetLengthSid = modadvapi32.NewProc("GetLengthSid")
procGetNamedSecurityInfoW = modadvapi32.NewProc("GetNamedSecurityInfoW") procGetNamedSecurityInfoW = modadvapi32.NewProc("GetNamedSecurityInfoW")
procGetSecurityDescriptorControl = modadvapi32.NewProc("GetSecurityDescriptorControl") procGetSecurityDescriptorControl = modadvapi32.NewProc("GetSecurityDescriptorControl")
@ -1224,6 +1225,14 @@ func setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCE
return return
} }
func GetAce(acl *ACL, aceIndex uint32, pAce **ACCESS_ALLOWED_ACE) (ret error) {
r0, _, _ := syscall.Syscall(procGetAce.Addr(), 3, uintptr(unsafe.Pointer(acl)), uintptr(aceIndex), uintptr(unsafe.Pointer(pAce)))
if r0 == 0 {
ret = GetLastError()
}
return
}
func SetKernelObjectSecurity(handle Handle, securityInformation SECURITY_INFORMATION, securityDescriptor *SECURITY_DESCRIPTOR) (err error) { func SetKernelObjectSecurity(handle Handle, securityInformation SECURITY_INFORMATION, securityDescriptor *SECURITY_DESCRIPTOR) (err error) {
r1, _, e1 := syscall.Syscall(procSetKernelObjectSecurity.Addr(), 3, uintptr(handle), uintptr(securityInformation), uintptr(unsafe.Pointer(securityDescriptor))) r1, _, e1 := syscall.Syscall(procSetKernelObjectSecurity.Addr(), 3, uintptr(handle), uintptr(securityInformation), uintptr(unsafe.Pointer(securityDescriptor)))
if r1 == 0 { if r1 == 0 {

View File

@ -106,8 +106,21 @@ func PathEnclosingInterval(root *ast.File, start, end token.Pos) (path []ast.Nod
// Does augmented child strictly contain [start, end)? // Does augmented child strictly contain [start, end)?
if augPos <= start && end <= augEnd { if augPos <= start && end <= augEnd {
_, isToken := child.(tokenNode) if is[tokenNode](child) {
return isToken || visit(child) return true
}
// childrenOf elides the FuncType node beneath FuncDecl.
// Add it back here for TypeParams, Params, Results,
// all FieldLists). But we don't add it back for the "func" token
// even though it is is the tree at FuncDecl.Type.Func.
if decl, ok := node.(*ast.FuncDecl); ok {
if fields, ok := child.(*ast.FieldList); ok && fields != decl.Recv {
path = append(path, decl.Type)
}
}
return visit(child)
} }
// Does [start, end) overlap multiple children? // Does [start, end) overlap multiple children?
@ -313,6 +326,8 @@ func childrenOf(n ast.Node) []ast.Node {
// //
// As a workaround, we inline the case for FuncType // As a workaround, we inline the case for FuncType
// here and order things correctly. // here and order things correctly.
// We also need to insert the elided FuncType just
// before the 'visit' recursion.
// //
children = nil // discard ast.Walk(FuncDecl) info subtrees children = nil // discard ast.Walk(FuncDecl) info subtrees
children = append(children, tok(n.Type.Func, len("func"))) children = append(children, tok(n.Type.Func, len("func")))
@ -632,3 +647,8 @@ func NodeDescription(n ast.Node) string {
} }
panic(fmt.Sprintf("unexpected node type: %T", n)) panic(fmt.Sprintf("unexpected node type: %T", n))
} }
func is[T any](x any) bool {
_, ok := x.(T)
return ok
}

View File

@ -7,6 +7,7 @@ package astutil
import "go/ast" import "go/ast"
// Unparen returns e with any enclosing parentheses stripped. // Unparen returns e with any enclosing parentheses stripped.
// TODO(adonovan): use go1.22's ast.Unparen.
func Unparen(e ast.Expr) ast.Expr { func Unparen(e ast.Expr) ast.Expr {
for { for {
p, ok := e.(*ast.ParenExpr) p, ok := e.(*ast.ParenExpr)

View File

@ -200,12 +200,14 @@ func (i *Invocation) runWithFriendlyError(ctx context.Context, stdout, stderr io
return return
} }
func (i *Invocation) run(ctx context.Context, stdout, stderr io.Writer) error { // logf logs if i.Logf is non-nil.
log := i.Logf func (i *Invocation) logf(format string, args ...any) {
if log == nil { if i.Logf != nil {
log = func(string, ...interface{}) {} i.Logf(format, args...)
} }
}
func (i *Invocation) run(ctx context.Context, stdout, stderr io.Writer) error {
goArgs := []string{i.Verb} goArgs := []string{i.Verb}
appendModFile := func() { appendModFile := func() {
@ -277,7 +279,12 @@ func (i *Invocation) run(ctx context.Context, stdout, stderr io.Writer) error {
cmd.Dir = i.WorkingDir cmd.Dir = i.WorkingDir
} }
defer func(start time.Time) { log("%s for %v", time.Since(start), cmdDebugStr(cmd)) }(time.Now()) debugStr := cmdDebugStr(cmd)
i.logf("starting %v", debugStr)
start := time.Now()
defer func() {
i.logf("%s for %v", time.Since(start), debugStr)
}()
return runCmdContext(ctx, cmd) return runCmdContext(ctx, cmd)
} }
@ -514,7 +521,7 @@ func WriteOverlays(overlay map[string][]byte) (filename string, cleanup func(),
for k, v := range overlay { for k, v := range overlay {
// Use a unique basename for each file (001-foo.go), // Use a unique basename for each file (001-foo.go),
// to avoid creating nested directories. // to avoid creating nested directories.
base := fmt.Sprintf("%d-%s.go", 1+len(overlays), filepath.Base(k)) base := fmt.Sprintf("%d-%s", 1+len(overlays), filepath.Base(k))
filename := filepath.Join(dir, base) filename := filepath.Join(dir, base)
err := os.WriteFile(filename, v, 0666) err := os.WriteFile(filename, v, 0666)
if err != nil { if err != nil {

View File

@ -27,6 +27,7 @@ import (
"unicode" "unicode"
"unicode/utf8" "unicode/utf8"
"golang.org/x/sync/errgroup"
"golang.org/x/tools/go/ast/astutil" "golang.org/x/tools/go/ast/astutil"
"golang.org/x/tools/internal/event" "golang.org/x/tools/internal/event"
"golang.org/x/tools/internal/gocommand" "golang.org/x/tools/internal/gocommand"
@ -365,9 +366,7 @@ func (p *pass) load() ([]*ImportFix, bool) {
if p.loadRealPackageNames { if p.loadRealPackageNames {
err := p.loadPackageNames(append(imports, p.candidates...)) err := p.loadPackageNames(append(imports, p.candidates...))
if err != nil { if err != nil {
if p.env.Logf != nil { p.env.logf("loading package names: %v", err)
p.env.Logf("loading package names: %v", err)
}
return nil, false return nil, false
} }
} }
@ -563,7 +562,14 @@ func (p *pass) addCandidate(imp *ImportInfo, pkg *packageInfo) {
// fixImports adds and removes imports from f so that all its references are // fixImports adds and removes imports from f so that all its references are
// satisfied and there are no unused imports. // satisfied and there are no unused imports.
func fixImports(fset *token.FileSet, f *ast.File, filename string, env *ProcessEnv) error { //
// This is declared as a variable rather than a function so goimports can
// easily be extended by adding a file with an init function.
//
// DO NOT REMOVE: used internally at Google.
var fixImports = fixImportsDefault
func fixImportsDefault(fset *token.FileSet, f *ast.File, filename string, env *ProcessEnv) error {
fixes, err := getFixes(context.Background(), fset, f, filename, env) fixes, err := getFixes(context.Background(), fset, f, filename, env)
if err != nil { if err != nil {
return err return err
@ -580,9 +586,7 @@ func getFixes(ctx context.Context, fset *token.FileSet, f *ast.File, filename st
return nil, err return nil, err
} }
srcDir := filepath.Dir(abs) srcDir := filepath.Dir(abs)
if env.Logf != nil { env.logf("fixImports(filename=%q), abs=%q, srcDir=%q ...", filename, abs, srcDir)
env.Logf("fixImports(filename=%q), abs=%q, srcDir=%q ...", filename, abs, srcDir)
}
// First pass: looking only at f, and using the naive algorithm to // First pass: looking only at f, and using the naive algorithm to
// derive package names from import paths, see if the file is already // derive package names from import paths, see if the file is already
@ -1014,16 +1018,26 @@ func (e *ProcessEnv) GetResolver() (Resolver, error) {
// already know the view type. // already know the view type.
if len(e.Env["GOMOD"]) == 0 && len(e.Env["GOWORK"]) == 0 { if len(e.Env["GOMOD"]) == 0 && len(e.Env["GOWORK"]) == 0 {
e.resolver = newGopathResolver(e) e.resolver = newGopathResolver(e)
e.logf("created gopath resolver")
} else if r, err := newModuleResolver(e, e.ModCache); err != nil { } else if r, err := newModuleResolver(e, e.ModCache); err != nil {
e.resolverErr = err e.resolverErr = err
e.logf("failed to create module resolver: %v", err)
} else { } else {
e.resolver = Resolver(r) e.resolver = Resolver(r)
e.logf("created module resolver")
} }
} }
return e.resolver, e.resolverErr return e.resolver, e.resolverErr
} }
// logf logs if e.Logf is non-nil.
func (e *ProcessEnv) logf(format string, args ...any) {
if e.Logf != nil {
e.Logf(format, args...)
}
}
// buildContext returns the build.Context to use for matching files. // buildContext returns the build.Context to use for matching files.
// //
// TODO(rfindley): support dynamic GOOS, GOARCH here, when doing cross-platform // TODO(rfindley): support dynamic GOOS, GOARCH here, when doing cross-platform
@ -1127,8 +1141,8 @@ type Resolver interface {
// scan works with callback to search for packages. See scanCallback for details. // scan works with callback to search for packages. See scanCallback for details.
scan(ctx context.Context, callback *scanCallback) error scan(ctx context.Context, callback *scanCallback) error
// loadExports returns the set of exported symbols in the package at dir. // loadExports returns the package name and set of exported symbols in the
// loadExports may be called concurrently. // package at dir. loadExports may be called concurrently.
loadExports(ctx context.Context, pkg *pkg, includeTest bool) (string, []stdlib.Symbol, error) loadExports(ctx context.Context, pkg *pkg, includeTest bool) (string, []stdlib.Symbol, error)
// scoreImportPath returns the relevance for an import path. // scoreImportPath returns the relevance for an import path.
@ -1205,54 +1219,52 @@ func addExternalCandidates(ctx context.Context, pass *pass, refs references, fil
imp *ImportInfo imp *ImportInfo
pkg *packageInfo pkg *packageInfo
} }
results := make(chan result, len(refs)) results := make([]*result, len(refs))
ctx, cancel := context.WithCancel(ctx) g, ctx := errgroup.WithContext(ctx)
var wg sync.WaitGroup
defer func() {
cancel()
wg.Wait()
}()
var (
firstErr error
firstErrOnce sync.Once
)
for pkgName, symbols := range refs {
wg.Add(1)
go func(pkgName string, symbols map[string]bool) {
defer wg.Done()
found, err := findImport(ctx, pass, found[pkgName], pkgName, symbols) searcher := symbolSearcher{
logf: pass.env.logf,
if err != nil { srcDir: pass.srcDir,
firstErrOnce.Do(func() { xtest: strings.HasSuffix(pass.f.Name.Name, "_test"),
firstErr = err loadExports: resolver.loadExports,
cancel()
})
return
} }
i := 0
for pkgName, symbols := range refs {
index := i // claim an index in results
i++
pkgName := pkgName
symbols := symbols
g.Go(func() error {
found, err := searcher.search(ctx, found[pkgName], pkgName, symbols)
if err != nil {
return err
}
if found == nil { if found == nil {
return // No matching package. return nil // No matching package.
} }
imp := &ImportInfo{ imp := &ImportInfo{
ImportPath: found.importPathShort, ImportPath: found.importPathShort,
} }
pkg := &packageInfo{ pkg := &packageInfo{
name: pkgName, name: pkgName,
exports: symbols, exports: symbols,
} }
results <- result{imp, pkg} results[index] = &result{imp, pkg}
}(pkgName, symbols) return nil
})
}
if err := g.Wait(); err != nil {
return err
} }
go func() {
wg.Wait()
close(results)
}()
for result := range results { for _, result := range results {
if result == nil {
continue
}
// Don't offer completions that would shadow predeclared // Don't offer completions that would shadow predeclared
// names, such as github.com/coreos/etcd/error. // names, such as github.com/coreos/etcd/error.
if types.Universe.Lookup(result.pkg.name) != nil { // predeclared if types.Universe.Lookup(result.pkg.name) != nil { // predeclared
@ -1266,7 +1278,7 @@ func addExternalCandidates(ctx context.Context, pass *pass, refs references, fil
} }
pass.addCandidate(result.imp, result.pkg) pass.addCandidate(result.imp, result.pkg)
} }
return firstErr return nil
} }
// notIdentifier reports whether ch is an invalid identifier character. // notIdentifier reports whether ch is an invalid identifier character.
@ -1610,9 +1622,7 @@ func loadExportsFromFiles(ctx context.Context, env *ProcessEnv, dir string, incl
fullFile := filepath.Join(dir, fi.Name()) fullFile := filepath.Join(dir, fi.Name())
f, err := parser.ParseFile(fset, fullFile, nil, 0) f, err := parser.ParseFile(fset, fullFile, nil, 0)
if err != nil { if err != nil {
if env.Logf != nil { env.logf("error parsing %v: %v", fullFile, err)
env.Logf("error parsing %v: %v", fullFile, err)
}
continue continue
} }
if f.Name.Name == "documentation" { if f.Name.Name == "documentation" {
@ -1648,9 +1658,7 @@ func loadExportsFromFiles(ctx context.Context, env *ProcessEnv, dir string, incl
} }
sortSymbols(exports) sortSymbols(exports)
if env.Logf != nil { env.logf("loaded exports in dir %v (package %v): %v", dir, pkgName, exports)
env.Logf("loaded exports in dir %v (package %v): %v", dir, pkgName, exports)
}
return pkgName, exports, nil return pkgName, exports, nil
} }
@ -1660,25 +1668,39 @@ func sortSymbols(syms []stdlib.Symbol) {
}) })
} }
// findImport searches for a package with the given symbols. // A symbolSearcher searches for a package with a set of symbols, among a set
// If no package is found, findImport returns ("", false, nil) // of candidates. See [symbolSearcher.search].
func findImport(ctx context.Context, pass *pass, candidates []pkgDistance, pkgName string, symbols map[string]bool) (*pkg, error) { //
// The search occurs within the scope of a single file, with context captured
// in srcDir and xtest.
type symbolSearcher struct {
logf func(string, ...any)
srcDir string // directory containing the file
xtest bool // if set, the file containing is an x_test file
loadExports func(ctx context.Context, pkg *pkg, includeTest bool) (string, []stdlib.Symbol, error)
}
// search searches the provided candidates for a package containing all
// exported symbols.
//
// If successful, returns the resulting package.
func (s *symbolSearcher) search(ctx context.Context, candidates []pkgDistance, pkgName string, symbols map[string]bool) (*pkg, error) {
// Sort the candidates by their import package length, // Sort the candidates by their import package length,
// assuming that shorter package names are better than long // assuming that shorter package names are better than long
// ones. Note that this sorts by the de-vendored name, so // ones. Note that this sorts by the de-vendored name, so
// there's no "penalty" for vendoring. // there's no "penalty" for vendoring.
sort.Sort(byDistanceOrImportPathShortLength(candidates)) sort.Sort(byDistanceOrImportPathShortLength(candidates))
if pass.env.Logf != nil { if s.logf != nil {
for i, c := range candidates { for i, c := range candidates {
pass.env.Logf("%s candidate %d/%d: %v in %v", pkgName, i+1, len(candidates), c.pkg.importPathShort, c.pkg.dir) s.logf("%s candidate %d/%d: %v in %v", pkgName, i+1, len(candidates), c.pkg.importPathShort, c.pkg.dir)
} }
} }
resolver, err := pass.env.GetResolver()
if err != nil {
return nil, err
}
// Collect exports for packages with matching names. // Arrange rescv so that we can we can await results in order of relevance
// and exit as soon as we find the first match.
//
// Search with bounded concurrency, returning as soon as the first result
// among rescv is non-nil.
rescv := make([]chan *pkg, len(candidates)) rescv := make([]chan *pkg, len(candidates))
for i := range candidates { for i := range candidates {
rescv[i] = make(chan *pkg, 1) rescv[i] = make(chan *pkg, 1)
@ -1686,6 +1708,7 @@ func findImport(ctx context.Context, pass *pass, candidates []pkgDistance, pkgNa
const maxConcurrentPackageImport = 4 const maxConcurrentPackageImport = 4
loadExportsSem := make(chan struct{}, maxConcurrentPackageImport) loadExportsSem := make(chan struct{}, maxConcurrentPackageImport)
// Ensure that all work is completed at exit.
ctx, cancel := context.WithCancel(ctx) ctx, cancel := context.WithCancel(ctx)
var wg sync.WaitGroup var wg sync.WaitGroup
defer func() { defer func() {
@ -1693,6 +1716,7 @@ func findImport(ctx context.Context, pass *pass, candidates []pkgDistance, pkgNa
wg.Wait() wg.Wait()
}() }()
// Start the search.
wg.Add(1) wg.Add(1)
go func() { go func() {
defer wg.Done() defer wg.Done()
@ -1703,53 +1727,65 @@ func findImport(ctx context.Context, pass *pass, candidates []pkgDistance, pkgNa
return return
} }
i := i
c := c
wg.Add(1) wg.Add(1)
go func(c pkgDistance, resc chan<- *pkg) { go func() {
defer func() { defer func() {
<-loadExportsSem <-loadExportsSem
wg.Done() wg.Done()
}() }()
if s.logf != nil {
if pass.env.Logf != nil { s.logf("loading exports in dir %s (seeking package %s)", c.pkg.dir, pkgName)
pass.env.Logf("loading exports in dir %s (seeking package %s)", c.pkg.dir, pkgName)
} }
// If we're an x_test, load the package under test's test variant. pkg, err := s.searchOne(ctx, c, symbols)
includeTest := strings.HasSuffix(pass.f.Name.Name, "_test") && c.pkg.dir == pass.srcDir
_, exports, err := resolver.loadExports(ctx, c.pkg, includeTest)
if err != nil { if err != nil {
if pass.env.Logf != nil { if s.logf != nil && ctx.Err() == nil {
pass.env.Logf("loading exports in dir %s (seeking package %s): %v", c.pkg.dir, pkgName, err) s.logf("loading exports in dir %s (seeking package %s): %v", c.pkg.dir, pkgName, err)
} }
resc <- nil pkg = nil
return }
rescv[i] <- pkg // may be nil
}()
}
}()
// Await the first (best) result.
for _, resc := range rescv {
select {
case r := <-resc:
if r != nil {
return r, nil
}
case <-ctx.Done():
return nil, ctx.Err()
}
}
return nil, nil
}
func (s *symbolSearcher) searchOne(ctx context.Context, c pkgDistance, symbols map[string]bool) (*pkg, error) {
if ctx.Err() != nil {
return nil, ctx.Err()
}
// If we're considering the package under test from an x_test, load the
// test variant.
includeTest := s.xtest && c.pkg.dir == s.srcDir
_, exports, err := s.loadExports(ctx, c.pkg, includeTest)
if err != nil {
return nil, err
} }
exportsMap := make(map[string]bool, len(exports)) exportsMap := make(map[string]bool, len(exports))
for _, sym := range exports { for _, sym := range exports {
exportsMap[sym.Name] = true exportsMap[sym.Name] = true
} }
// If it doesn't have the right
// symbols, send nil to mean no match.
for symbol := range symbols { for symbol := range symbols {
if !exportsMap[symbol] { if !exportsMap[symbol] {
resc <- nil return nil, nil // no match
return
} }
} }
resc <- c.pkg return c.pkg, nil
}(c, rescv[i])
}
}()
for _, resc := range rescv {
pkg := <-resc
if pkg == nil {
continue
}
return pkg, nil
}
return nil, nil
} }
// pkgIsCandidate reports whether pkg is a candidate for satisfying the // pkgIsCandidate reports whether pkg is a candidate for satisfying the
@ -1771,58 +1807,24 @@ func pkgIsCandidate(filename string, refs references, pkg *pkg) bool {
} }
// Speed optimization to minimize disk I/O: // Speed optimization to minimize disk I/O:
// the last two components on disk must contain the
// package name somewhere.
// //
// This permits mismatch naming like directory // Use the matchesPath heuristic to filter to package paths that could
// "go-foo" being package "foo", or "pkg.v3" being "pkg", // reasonably match a dangling reference.
// or directory "google.golang.org/api/cloudbilling/v1" //
// being package "cloudbilling", but doesn't // This permits mismatch naming like directory "go-foo" being package "foo",
// permit a directory "foo" to be package // or "pkg.v3" being "pkg", or directory
// "bar", which is strongly discouraged // "google.golang.org/api/cloudbilling/v1" being package "cloudbilling", but
// anyway. There's no reason goimports needs // doesn't permit a directory "foo" to be package "bar", which is strongly
// to be slow just to accommodate that. // discouraged anyway. There's no reason goimports needs to be slow just to
// accommodate that.
for pkgIdent := range refs { for pkgIdent := range refs {
lastTwo := lastTwoComponents(pkg.importPathShort) if matchesPath(pkgIdent, pkg.importPathShort) {
if strings.Contains(lastTwo, pkgIdent) {
return true
}
if hasHyphenOrUpperASCII(lastTwo) && !hasHyphenOrUpperASCII(pkgIdent) {
lastTwo = lowerASCIIAndRemoveHyphen(lastTwo)
if strings.Contains(lastTwo, pkgIdent) {
return true
}
}
}
return false
}
func hasHyphenOrUpperASCII(s string) bool {
for i := 0; i < len(s); i++ {
b := s[i]
if b == '-' || ('A' <= b && b <= 'Z') {
return true return true
} }
} }
return false return false
} }
func lowerASCIIAndRemoveHyphen(s string) (ret string) {
buf := make([]byte, 0, len(s))
for i := 0; i < len(s); i++ {
b := s[i]
switch {
case b == '-':
continue
case 'A' <= b && b <= 'Z':
buf = append(buf, b+('a'-'A'))
default:
buf = append(buf, b)
}
}
return string(buf)
}
// canUse reports whether the package in dir is usable from filename, // canUse reports whether the package in dir is usable from filename,
// respecting the Go "internal" and "vendor" visibility rules. // respecting the Go "internal" and "vendor" visibility rules.
func canUse(filename, dir string) bool { func canUse(filename, dir string) bool {
@ -1863,19 +1865,84 @@ func canUse(filename, dir string) bool {
return !strings.Contains(relSlash, "/vendor/") && !strings.Contains(relSlash, "/internal/") && !strings.HasSuffix(relSlash, "/internal") return !strings.Contains(relSlash, "/vendor/") && !strings.Contains(relSlash, "/internal/") && !strings.HasSuffix(relSlash, "/internal")
} }
// lastTwoComponents returns at most the last two path components // matchesPath reports whether ident may match a potential package name
// of v, using either / or \ as the path separator. // referred to by path, using heuristics to filter out unidiomatic package
func lastTwoComponents(v string) string { // names.
//
// Specifically, it checks whether either of the last two '/'- or '\'-delimited
// path segments matches the identifier. The segment-matching heuristic must
// allow for various conventions around segment naming, including go-foo,
// foo-go, and foo.v3. To handle all of these, matching considers both (1) the
// entire segment, ignoring '-' and '.', as well as (2) the last subsegment
// separated by '-' or '.'. So the segment foo-go matches all of the following
// identifiers: foo, go, and foogo. All matches are case insensitive (for ASCII
// identifiers).
//
// See the docstring for [pkgIsCandidate] for an explanation of how this
// heuristic filters potential candidate packages.
func matchesPath(ident, path string) bool {
// Ignore case, for ASCII.
lowerIfASCII := func(b byte) byte {
if 'A' <= b && b <= 'Z' {
return b + ('a' - 'A')
}
return b
}
// match reports whether path[start:end] matches ident, ignoring [.-].
match := func(start, end int) bool {
ii := len(ident) - 1 // current byte in ident
pi := end - 1 // current byte in path
for ; pi >= start && ii >= 0; pi-- {
pb := path[pi]
if pb == '-' || pb == '.' {
continue
}
pb = lowerIfASCII(pb)
ib := lowerIfASCII(ident[ii])
if pb != ib {
return false
}
ii--
}
return ii < 0 && pi < start // all bytes matched
}
// segmentEnd and subsegmentEnd hold the end points of the current segment
// and subsegment intervals.
segmentEnd := len(path)
subsegmentEnd := len(path)
// Count slashes; we only care about the last two segments.
nslash := 0 nslash := 0
for i := len(v) - 1; i >= 0; i-- {
if v[i] == '/' || v[i] == '\\' { for i := len(path) - 1; i >= 0; i-- {
switch b := path[i]; b {
// TODO(rfindley): we handle backlashes here only because the previous
// heuristic handled backslashes. This is perhaps overly defensive, but is
// the result of many lessons regarding Chesterton's fence and the
// goimports codebase.
//
// However, this function is only ever called with something called an
// 'importPath'. Is it possible that this is a real import path, and
// therefore we need only consider forward slashes?
case '/', '\\':
if match(i+1, segmentEnd) || match(i+1, subsegmentEnd) {
return true
}
nslash++ nslash++
if nslash == 2 { if nslash == 2 {
return v[i:] return false // did not match above
}
segmentEnd, subsegmentEnd = i, i // reset
case '-', '.':
if match(i+1, subsegmentEnd) {
return true
}
subsegmentEnd = i
} }
} }
} return match(0, segmentEnd) || match(0, subsegmentEnd)
return v
} }
type visitFn func(node ast.Node) ast.Visitor type visitFn func(node ast.Node) ast.Visitor

View File

@ -265,9 +265,7 @@ func (r *ModuleResolver) initAllMods() error {
return err return err
} }
if mod.Dir == "" { if mod.Dir == "" {
if r.env.Logf != nil { r.env.logf("module %v has not been downloaded and will be ignored", mod.Path)
r.env.Logf("module %v has not been downloaded and will be ignored", mod.Path)
}
// Can't do anything with a module that's not downloaded. // Can't do anything with a module that's not downloaded.
continue continue
} }
@ -766,9 +764,7 @@ func (r *ModuleResolver) scanDirForPackage(root gopathwalk.Root, dir string) dir
} }
modPath, err := module.UnescapePath(filepath.ToSlash(matches[1])) modPath, err := module.UnescapePath(filepath.ToSlash(matches[1]))
if err != nil { if err != nil {
if r.env.Logf != nil { r.env.logf("decoding module cache path %q: %v", subdir, err)
r.env.Logf("decoding module cache path %q: %v", subdir, err)
}
return directoryPackageInfo{ return directoryPackageInfo{
status: directoryScanned, status: directoryScanned,
err: fmt.Errorf("decoding module cache path %q: %v", subdir, err), err: fmt.Errorf("decoding module cache path %q: %v", subdir, err),

View File

@ -23,6 +23,7 @@ var PackageSymbols = map[string][]Symbol{
{"ErrWriteAfterClose", Var, 0}, {"ErrWriteAfterClose", Var, 0},
{"ErrWriteTooLong", Var, 0}, {"ErrWriteTooLong", Var, 0},
{"FileInfoHeader", Func, 1}, {"FileInfoHeader", Func, 1},
{"FileInfoNames", Type, 23},
{"Format", Type, 10}, {"Format", Type, 10},
{"FormatGNU", Const, 10}, {"FormatGNU", Const, 10},
{"FormatPAX", Const, 10}, {"FormatPAX", Const, 10},
@ -820,6 +821,7 @@ var PackageSymbols = map[string][]Symbol{
{"(*ConnectionState).ExportKeyingMaterial", Method, 11}, {"(*ConnectionState).ExportKeyingMaterial", Method, 11},
{"(*Dialer).Dial", Method, 15}, {"(*Dialer).Dial", Method, 15},
{"(*Dialer).DialContext", Method, 15}, {"(*Dialer).DialContext", Method, 15},
{"(*ECHRejectionError).Error", Method, 23},
{"(*QUICConn).Close", Method, 21}, {"(*QUICConn).Close", Method, 21},
{"(*QUICConn).ConnectionState", Method, 21}, {"(*QUICConn).ConnectionState", Method, 21},
{"(*QUICConn).HandleData", Method, 21}, {"(*QUICConn).HandleData", Method, 21},
@ -827,6 +829,7 @@ var PackageSymbols = map[string][]Symbol{
{"(*QUICConn).SendSessionTicket", Method, 21}, {"(*QUICConn).SendSessionTicket", Method, 21},
{"(*QUICConn).SetTransportParameters", Method, 21}, {"(*QUICConn).SetTransportParameters", Method, 21},
{"(*QUICConn).Start", Method, 21}, {"(*QUICConn).Start", Method, 21},
{"(*QUICConn).StoreSession", Method, 23},
{"(*SessionState).Bytes", Method, 21}, {"(*SessionState).Bytes", Method, 21},
{"(AlertError).Error", Method, 21}, {"(AlertError).Error", Method, 21},
{"(ClientAuthType).String", Method, 15}, {"(ClientAuthType).String", Method, 15},
@ -877,6 +880,8 @@ var PackageSymbols = map[string][]Symbol{
{"Config.ClientSessionCache", Field, 3}, {"Config.ClientSessionCache", Field, 3},
{"Config.CurvePreferences", Field, 3}, {"Config.CurvePreferences", Field, 3},
{"Config.DynamicRecordSizingDisabled", Field, 7}, {"Config.DynamicRecordSizingDisabled", Field, 7},
{"Config.EncryptedClientHelloConfigList", Field, 23},
{"Config.EncryptedClientHelloRejectionVerify", Field, 23},
{"Config.GetCertificate", Field, 4}, {"Config.GetCertificate", Field, 4},
{"Config.GetClientCertificate", Field, 8}, {"Config.GetClientCertificate", Field, 8},
{"Config.GetConfigForClient", Field, 8}, {"Config.GetConfigForClient", Field, 8},
@ -902,6 +907,7 @@ var PackageSymbols = map[string][]Symbol{
{"ConnectionState", Type, 0}, {"ConnectionState", Type, 0},
{"ConnectionState.CipherSuite", Field, 0}, {"ConnectionState.CipherSuite", Field, 0},
{"ConnectionState.DidResume", Field, 1}, {"ConnectionState.DidResume", Field, 1},
{"ConnectionState.ECHAccepted", Field, 23},
{"ConnectionState.HandshakeComplete", Field, 0}, {"ConnectionState.HandshakeComplete", Field, 0},
{"ConnectionState.NegotiatedProtocol", Field, 0}, {"ConnectionState.NegotiatedProtocol", Field, 0},
{"ConnectionState.NegotiatedProtocolIsMutual", Field, 0}, {"ConnectionState.NegotiatedProtocolIsMutual", Field, 0},
@ -925,6 +931,8 @@ var PackageSymbols = map[string][]Symbol{
{"ECDSAWithP384AndSHA384", Const, 8}, {"ECDSAWithP384AndSHA384", Const, 8},
{"ECDSAWithP521AndSHA512", Const, 8}, {"ECDSAWithP521AndSHA512", Const, 8},
{"ECDSAWithSHA1", Const, 10}, {"ECDSAWithSHA1", Const, 10},
{"ECHRejectionError", Type, 23},
{"ECHRejectionError.RetryConfigList", Field, 23},
{"Ed25519", Const, 13}, {"Ed25519", Const, 13},
{"InsecureCipherSuites", Func, 14}, {"InsecureCipherSuites", Func, 14},
{"Listen", Func, 0}, {"Listen", Func, 0},
@ -943,6 +951,7 @@ var PackageSymbols = map[string][]Symbol{
{"ParseSessionState", Func, 21}, {"ParseSessionState", Func, 21},
{"QUICClient", Func, 21}, {"QUICClient", Func, 21},
{"QUICConfig", Type, 21}, {"QUICConfig", Type, 21},
{"QUICConfig.EnableStoreSessionEvent", Field, 23},
{"QUICConfig.TLSConfig", Field, 21}, {"QUICConfig.TLSConfig", Field, 21},
{"QUICConn", Type, 21}, {"QUICConn", Type, 21},
{"QUICEncryptionLevel", Type, 21}, {"QUICEncryptionLevel", Type, 21},
@ -954,16 +963,20 @@ var PackageSymbols = map[string][]Symbol{
{"QUICEvent.Data", Field, 21}, {"QUICEvent.Data", Field, 21},
{"QUICEvent.Kind", Field, 21}, {"QUICEvent.Kind", Field, 21},
{"QUICEvent.Level", Field, 21}, {"QUICEvent.Level", Field, 21},
{"QUICEvent.SessionState", Field, 23},
{"QUICEvent.Suite", Field, 21}, {"QUICEvent.Suite", Field, 21},
{"QUICEventKind", Type, 21}, {"QUICEventKind", Type, 21},
{"QUICHandshakeDone", Const, 21}, {"QUICHandshakeDone", Const, 21},
{"QUICNoEvent", Const, 21}, {"QUICNoEvent", Const, 21},
{"QUICRejectedEarlyData", Const, 21}, {"QUICRejectedEarlyData", Const, 21},
{"QUICResumeSession", Const, 23},
{"QUICServer", Func, 21}, {"QUICServer", Func, 21},
{"QUICSessionTicketOptions", Type, 21}, {"QUICSessionTicketOptions", Type, 21},
{"QUICSessionTicketOptions.EarlyData", Field, 21}, {"QUICSessionTicketOptions.EarlyData", Field, 21},
{"QUICSessionTicketOptions.Extra", Field, 23},
{"QUICSetReadSecret", Const, 21}, {"QUICSetReadSecret", Const, 21},
{"QUICSetWriteSecret", Const, 21}, {"QUICSetWriteSecret", Const, 21},
{"QUICStoreSession", Const, 23},
{"QUICTransportParameters", Const, 21}, {"QUICTransportParameters", Const, 21},
{"QUICTransportParametersRequired", Const, 21}, {"QUICTransportParametersRequired", Const, 21},
{"QUICWriteData", Const, 21}, {"QUICWriteData", Const, 21},
@ -1036,6 +1049,8 @@ var PackageSymbols = map[string][]Symbol{
{"(*Certificate).Verify", Method, 0}, {"(*Certificate).Verify", Method, 0},
{"(*Certificate).VerifyHostname", Method, 0}, {"(*Certificate).VerifyHostname", Method, 0},
{"(*CertificateRequest).CheckSignature", Method, 5}, {"(*CertificateRequest).CheckSignature", Method, 5},
{"(*OID).UnmarshalBinary", Method, 23},
{"(*OID).UnmarshalText", Method, 23},
{"(*RevocationList).CheckSignatureFrom", Method, 19}, {"(*RevocationList).CheckSignatureFrom", Method, 19},
{"(CertificateInvalidError).Error", Method, 0}, {"(CertificateInvalidError).Error", Method, 0},
{"(ConstraintViolationError).Error", Method, 0}, {"(ConstraintViolationError).Error", Method, 0},
@ -1043,6 +1058,8 @@ var PackageSymbols = map[string][]Symbol{
{"(InsecureAlgorithmError).Error", Method, 6}, {"(InsecureAlgorithmError).Error", Method, 6},
{"(OID).Equal", Method, 22}, {"(OID).Equal", Method, 22},
{"(OID).EqualASN1OID", Method, 22}, {"(OID).EqualASN1OID", Method, 22},
{"(OID).MarshalBinary", Method, 23},
{"(OID).MarshalText", Method, 23},
{"(OID).String", Method, 22}, {"(OID).String", Method, 22},
{"(PublicKeyAlgorithm).String", Method, 10}, {"(PublicKeyAlgorithm).String", Method, 10},
{"(SignatureAlgorithm).String", Method, 6}, {"(SignatureAlgorithm).String", Method, 6},
@ -1196,6 +1213,7 @@ var PackageSymbols = map[string][]Symbol{
{"ParseCertificates", Func, 0}, {"ParseCertificates", Func, 0},
{"ParseDERCRL", Func, 0}, {"ParseDERCRL", Func, 0},
{"ParseECPrivateKey", Func, 1}, {"ParseECPrivateKey", Func, 1},
{"ParseOID", Func, 23},
{"ParsePKCS1PrivateKey", Func, 0}, {"ParsePKCS1PrivateKey", Func, 0},
{"ParsePKCS1PublicKey", Func, 10}, {"ParsePKCS1PublicKey", Func, 10},
{"ParsePKCS8PrivateKey", Func, 0}, {"ParsePKCS8PrivateKey", Func, 0},
@ -2541,6 +2559,7 @@ var PackageSymbols = map[string][]Symbol{
{"PT_NOTE", Const, 0}, {"PT_NOTE", Const, 0},
{"PT_NULL", Const, 0}, {"PT_NULL", Const, 0},
{"PT_OPENBSD_BOOTDATA", Const, 16}, {"PT_OPENBSD_BOOTDATA", Const, 16},
{"PT_OPENBSD_NOBTCFI", Const, 23},
{"PT_OPENBSD_RANDOMIZE", Const, 16}, {"PT_OPENBSD_RANDOMIZE", Const, 16},
{"PT_OPENBSD_WXNEEDED", Const, 16}, {"PT_OPENBSD_WXNEEDED", Const, 16},
{"PT_PAX_FLAGS", Const, 16}, {"PT_PAX_FLAGS", Const, 16},
@ -3620,13 +3639,16 @@ var PackageSymbols = map[string][]Symbol{
{"STT_COMMON", Const, 0}, {"STT_COMMON", Const, 0},
{"STT_FILE", Const, 0}, {"STT_FILE", Const, 0},
{"STT_FUNC", Const, 0}, {"STT_FUNC", Const, 0},
{"STT_GNU_IFUNC", Const, 23},
{"STT_HIOS", Const, 0}, {"STT_HIOS", Const, 0},
{"STT_HIPROC", Const, 0}, {"STT_HIPROC", Const, 0},
{"STT_LOOS", Const, 0}, {"STT_LOOS", Const, 0},
{"STT_LOPROC", Const, 0}, {"STT_LOPROC", Const, 0},
{"STT_NOTYPE", Const, 0}, {"STT_NOTYPE", Const, 0},
{"STT_OBJECT", Const, 0}, {"STT_OBJECT", Const, 0},
{"STT_RELC", Const, 23},
{"STT_SECTION", Const, 0}, {"STT_SECTION", Const, 0},
{"STT_SRELC", Const, 23},
{"STT_TLS", Const, 0}, {"STT_TLS", Const, 0},
{"STV_DEFAULT", Const, 0}, {"STV_DEFAULT", Const, 0},
{"STV_HIDDEN", Const, 0}, {"STV_HIDDEN", Const, 0},
@ -4544,11 +4566,14 @@ var PackageSymbols = map[string][]Symbol{
{"URLEncoding", Var, 0}, {"URLEncoding", Var, 0},
}, },
"encoding/binary": { "encoding/binary": {
{"Append", Func, 23},
{"AppendByteOrder", Type, 19}, {"AppendByteOrder", Type, 19},
{"AppendUvarint", Func, 19}, {"AppendUvarint", Func, 19},
{"AppendVarint", Func, 19}, {"AppendVarint", Func, 19},
{"BigEndian", Var, 0}, {"BigEndian", Var, 0},
{"ByteOrder", Type, 0}, {"ByteOrder", Type, 0},
{"Decode", Func, 23},
{"Encode", Func, 23},
{"LittleEndian", Var, 0}, {"LittleEndian", Var, 0},
{"MaxVarintLen16", Const, 0}, {"MaxVarintLen16", Const, 0},
{"MaxVarintLen32", Const, 0}, {"MaxVarintLen32", Const, 0},
@ -5308,6 +5333,7 @@ var PackageSymbols = map[string][]Symbol{
{"ParenExpr.Rparen", Field, 0}, {"ParenExpr.Rparen", Field, 0},
{"ParenExpr.X", Field, 0}, {"ParenExpr.X", Field, 0},
{"Pkg", Const, 0}, {"Pkg", Const, 0},
{"Preorder", Func, 23},
{"Print", Func, 0}, {"Print", Func, 0},
{"RECV", Const, 0}, {"RECV", Const, 0},
{"RangeStmt", Type, 0}, {"RangeStmt", Type, 0},
@ -5898,7 +5924,12 @@ var PackageSymbols = map[string][]Symbol{
}, },
"go/types": { "go/types": {
{"(*Alias).Obj", Method, 22}, {"(*Alias).Obj", Method, 22},
{"(*Alias).Origin", Method, 23},
{"(*Alias).Rhs", Method, 23},
{"(*Alias).SetTypeParams", Method, 23},
{"(*Alias).String", Method, 22}, {"(*Alias).String", Method, 22},
{"(*Alias).TypeArgs", Method, 23},
{"(*Alias).TypeParams", Method, 23},
{"(*Alias).Underlying", Method, 22}, {"(*Alias).Underlying", Method, 22},
{"(*ArgumentError).Error", Method, 18}, {"(*ArgumentError).Error", Method, 18},
{"(*ArgumentError).Unwrap", Method, 18}, {"(*ArgumentError).Unwrap", Method, 18},
@ -5943,6 +5974,7 @@ var PackageSymbols = map[string][]Symbol{
{"(*Func).Pkg", Method, 5}, {"(*Func).Pkg", Method, 5},
{"(*Func).Pos", Method, 5}, {"(*Func).Pos", Method, 5},
{"(*Func).Scope", Method, 5}, {"(*Func).Scope", Method, 5},
{"(*Func).Signature", Method, 23},
{"(*Func).String", Method, 5}, {"(*Func).String", Method, 5},
{"(*Func).Type", Method, 5}, {"(*Func).Type", Method, 5},
{"(*Info).ObjectOf", Method, 5}, {"(*Info).ObjectOf", Method, 5},
@ -6992,6 +7024,12 @@ var PackageSymbols = map[string][]Symbol{
{"TempFile", Func, 0}, {"TempFile", Func, 0},
{"WriteFile", Func, 0}, {"WriteFile", Func, 0},
}, },
"iter": {
{"Pull", Func, 23},
{"Pull2", Func, 23},
{"Seq", Type, 23},
{"Seq2", Type, 23},
},
"log": { "log": {
{"(*Logger).Fatal", Method, 0}, {"(*Logger).Fatal", Method, 0},
{"(*Logger).Fatalf", Method, 0}, {"(*Logger).Fatalf", Method, 0},
@ -7222,11 +7260,16 @@ var PackageSymbols = map[string][]Symbol{
{"Writer", Type, 0}, {"Writer", Type, 0},
}, },
"maps": { "maps": {
{"All", Func, 23},
{"Clone", Func, 21}, {"Clone", Func, 21},
{"Collect", Func, 23},
{"Copy", Func, 21}, {"Copy", Func, 21},
{"DeleteFunc", Func, 21}, {"DeleteFunc", Func, 21},
{"Equal", Func, 21}, {"Equal", Func, 21},
{"EqualFunc", Func, 21}, {"EqualFunc", Func, 21},
{"Insert", Func, 23},
{"Keys", Func, 23},
{"Values", Func, 23},
}, },
"math": { "math": {
{"Abs", Func, 0}, {"Abs", Func, 0},
@ -7617,6 +7660,7 @@ var PackageSymbols = map[string][]Symbol{
}, },
"math/rand/v2": { "math/rand/v2": {
{"(*ChaCha8).MarshalBinary", Method, 22}, {"(*ChaCha8).MarshalBinary", Method, 22},
{"(*ChaCha8).Read", Method, 23},
{"(*ChaCha8).Seed", Method, 22}, {"(*ChaCha8).Seed", Method, 22},
{"(*ChaCha8).Uint64", Method, 22}, {"(*ChaCha8).Uint64", Method, 22},
{"(*ChaCha8).UnmarshalBinary", Method, 22}, {"(*ChaCha8).UnmarshalBinary", Method, 22},
@ -7636,6 +7680,7 @@ var PackageSymbols = map[string][]Symbol{
{"(*Rand).NormFloat64", Method, 22}, {"(*Rand).NormFloat64", Method, 22},
{"(*Rand).Perm", Method, 22}, {"(*Rand).Perm", Method, 22},
{"(*Rand).Shuffle", Method, 22}, {"(*Rand).Shuffle", Method, 22},
{"(*Rand).Uint", Method, 23},
{"(*Rand).Uint32", Method, 22}, {"(*Rand).Uint32", Method, 22},
{"(*Rand).Uint32N", Method, 22}, {"(*Rand).Uint32N", Method, 22},
{"(*Rand).Uint64", Method, 22}, {"(*Rand).Uint64", Method, 22},
@ -7663,6 +7708,7 @@ var PackageSymbols = map[string][]Symbol{
{"Rand", Type, 22}, {"Rand", Type, 22},
{"Shuffle", Func, 22}, {"Shuffle", Func, 22},
{"Source", Type, 22}, {"Source", Type, 22},
{"Uint", Func, 23},
{"Uint32", Func, 22}, {"Uint32", Func, 22},
{"Uint32N", Func, 22}, {"Uint32N", Func, 22},
{"Uint64", Func, 22}, {"Uint64", Func, 22},
@ -7743,6 +7789,7 @@ var PackageSymbols = map[string][]Symbol{
{"(*DNSError).Error", Method, 0}, {"(*DNSError).Error", Method, 0},
{"(*DNSError).Temporary", Method, 0}, {"(*DNSError).Temporary", Method, 0},
{"(*DNSError).Timeout", Method, 0}, {"(*DNSError).Timeout", Method, 0},
{"(*DNSError).Unwrap", Method, 23},
{"(*Dialer).Dial", Method, 1}, {"(*Dialer).Dial", Method, 1},
{"(*Dialer).DialContext", Method, 7}, {"(*Dialer).DialContext", Method, 7},
{"(*Dialer).MultipathTCP", Method, 21}, {"(*Dialer).MultipathTCP", Method, 21},
@ -7809,6 +7856,7 @@ var PackageSymbols = map[string][]Symbol{
{"(*TCPConn).RemoteAddr", Method, 0}, {"(*TCPConn).RemoteAddr", Method, 0},
{"(*TCPConn).SetDeadline", Method, 0}, {"(*TCPConn).SetDeadline", Method, 0},
{"(*TCPConn).SetKeepAlive", Method, 0}, {"(*TCPConn).SetKeepAlive", Method, 0},
{"(*TCPConn).SetKeepAliveConfig", Method, 23},
{"(*TCPConn).SetKeepAlivePeriod", Method, 2}, {"(*TCPConn).SetKeepAlivePeriod", Method, 2},
{"(*TCPConn).SetLinger", Method, 0}, {"(*TCPConn).SetLinger", Method, 0},
{"(*TCPConn).SetNoDelay", Method, 0}, {"(*TCPConn).SetNoDelay", Method, 0},
@ -7922,6 +7970,7 @@ var PackageSymbols = map[string][]Symbol{
{"DNSError.IsTimeout", Field, 0}, {"DNSError.IsTimeout", Field, 0},
{"DNSError.Name", Field, 0}, {"DNSError.Name", Field, 0},
{"DNSError.Server", Field, 0}, {"DNSError.Server", Field, 0},
{"DNSError.UnwrapErr", Field, 23},
{"DefaultResolver", Var, 8}, {"DefaultResolver", Var, 8},
{"Dial", Func, 0}, {"Dial", Func, 0},
{"DialIP", Func, 0}, {"DialIP", Func, 0},
@ -7937,6 +7986,7 @@ var PackageSymbols = map[string][]Symbol{
{"Dialer.DualStack", Field, 2}, {"Dialer.DualStack", Field, 2},
{"Dialer.FallbackDelay", Field, 5}, {"Dialer.FallbackDelay", Field, 5},
{"Dialer.KeepAlive", Field, 3}, {"Dialer.KeepAlive", Field, 3},
{"Dialer.KeepAliveConfig", Field, 23},
{"Dialer.LocalAddr", Field, 1}, {"Dialer.LocalAddr", Field, 1},
{"Dialer.Resolver", Field, 8}, {"Dialer.Resolver", Field, 8},
{"Dialer.Timeout", Field, 1}, {"Dialer.Timeout", Field, 1},
@ -7989,10 +8039,16 @@ var PackageSymbols = map[string][]Symbol{
{"Interfaces", Func, 0}, {"Interfaces", Func, 0},
{"InvalidAddrError", Type, 0}, {"InvalidAddrError", Type, 0},
{"JoinHostPort", Func, 0}, {"JoinHostPort", Func, 0},
{"KeepAliveConfig", Type, 23},
{"KeepAliveConfig.Count", Field, 23},
{"KeepAliveConfig.Enable", Field, 23},
{"KeepAliveConfig.Idle", Field, 23},
{"KeepAliveConfig.Interval", Field, 23},
{"Listen", Func, 0}, {"Listen", Func, 0},
{"ListenConfig", Type, 11}, {"ListenConfig", Type, 11},
{"ListenConfig.Control", Field, 11}, {"ListenConfig.Control", Field, 11},
{"ListenConfig.KeepAlive", Field, 13}, {"ListenConfig.KeepAlive", Field, 13},
{"ListenConfig.KeepAliveConfig", Field, 23},
{"ListenIP", Func, 0}, {"ListenIP", Func, 0},
{"ListenMulticastUDP", Func, 0}, {"ListenMulticastUDP", Func, 0},
{"ListenPacket", Func, 0}, {"ListenPacket", Func, 0},
@ -8081,6 +8137,7 @@ var PackageSymbols = map[string][]Symbol{
{"(*Request).Context", Method, 7}, {"(*Request).Context", Method, 7},
{"(*Request).Cookie", Method, 0}, {"(*Request).Cookie", Method, 0},
{"(*Request).Cookies", Method, 0}, {"(*Request).Cookies", Method, 0},
{"(*Request).CookiesNamed", Method, 23},
{"(*Request).FormFile", Method, 0}, {"(*Request).FormFile", Method, 0},
{"(*Request).FormValue", Method, 0}, {"(*Request).FormValue", Method, 0},
{"(*Request).MultipartReader", Method, 0}, {"(*Request).MultipartReader", Method, 0},
@ -8148,7 +8205,9 @@ var PackageSymbols = map[string][]Symbol{
{"Cookie.HttpOnly", Field, 0}, {"Cookie.HttpOnly", Field, 0},
{"Cookie.MaxAge", Field, 0}, {"Cookie.MaxAge", Field, 0},
{"Cookie.Name", Field, 0}, {"Cookie.Name", Field, 0},
{"Cookie.Partitioned", Field, 23},
{"Cookie.Path", Field, 0}, {"Cookie.Path", Field, 0},
{"Cookie.Quoted", Field, 23},
{"Cookie.Raw", Field, 0}, {"Cookie.Raw", Field, 0},
{"Cookie.RawExpires", Field, 0}, {"Cookie.RawExpires", Field, 0},
{"Cookie.SameSite", Field, 11}, {"Cookie.SameSite", Field, 11},
@ -8225,7 +8284,9 @@ var PackageSymbols = map[string][]Symbol{
{"NoBody", Var, 8}, {"NoBody", Var, 8},
{"NotFound", Func, 0}, {"NotFound", Func, 0},
{"NotFoundHandler", Func, 0}, {"NotFoundHandler", Func, 0},
{"ParseCookie", Func, 23},
{"ParseHTTPVersion", Func, 0}, {"ParseHTTPVersion", Func, 0},
{"ParseSetCookie", Func, 23},
{"ParseTime", Func, 1}, {"ParseTime", Func, 1},
{"Post", Func, 0}, {"Post", Func, 0},
{"PostForm", Func, 0}, {"PostForm", Func, 0},
@ -8252,6 +8313,7 @@ var PackageSymbols = map[string][]Symbol{
{"Request.Host", Field, 0}, {"Request.Host", Field, 0},
{"Request.Method", Field, 0}, {"Request.Method", Field, 0},
{"Request.MultipartForm", Field, 0}, {"Request.MultipartForm", Field, 0},
{"Request.Pattern", Field, 23},
{"Request.PostForm", Field, 1}, {"Request.PostForm", Field, 1},
{"Request.Proto", Field, 0}, {"Request.Proto", Field, 0},
{"Request.ProtoMajor", Field, 0}, {"Request.ProtoMajor", Field, 0},
@ -8453,6 +8515,7 @@ var PackageSymbols = map[string][]Symbol{
{"DefaultRemoteAddr", Const, 0}, {"DefaultRemoteAddr", Const, 0},
{"NewRecorder", Func, 0}, {"NewRecorder", Func, 0},
{"NewRequest", Func, 7}, {"NewRequest", Func, 7},
{"NewRequestWithContext", Func, 23},
{"NewServer", Func, 0}, {"NewServer", Func, 0},
{"NewTLSServer", Func, 0}, {"NewTLSServer", Func, 0},
{"NewUnstartedServer", Func, 0}, {"NewUnstartedServer", Func, 0},
@ -8917,6 +8980,7 @@ var PackageSymbols = map[string][]Symbol{
{"Chown", Func, 0}, {"Chown", Func, 0},
{"Chtimes", Func, 0}, {"Chtimes", Func, 0},
{"Clearenv", Func, 0}, {"Clearenv", Func, 0},
{"CopyFS", Func, 23},
{"Create", Func, 0}, {"Create", Func, 0},
{"CreateTemp", Func, 16}, {"CreateTemp", Func, 16},
{"DevNull", Const, 0}, {"DevNull", Const, 0},
@ -9150,6 +9214,7 @@ var PackageSymbols = map[string][]Symbol{
{"IsLocal", Func, 20}, {"IsLocal", Func, 20},
{"Join", Func, 0}, {"Join", Func, 0},
{"ListSeparator", Const, 0}, {"ListSeparator", Const, 0},
{"Localize", Func, 23},
{"Match", Func, 0}, {"Match", Func, 0},
{"Rel", Func, 0}, {"Rel", Func, 0},
{"Separator", Const, 0}, {"Separator", Const, 0},
@ -9232,6 +9297,8 @@ var PackageSymbols = map[string][]Symbol{
{"(Value).Pointer", Method, 0}, {"(Value).Pointer", Method, 0},
{"(Value).Recv", Method, 0}, {"(Value).Recv", Method, 0},
{"(Value).Send", Method, 0}, {"(Value).Send", Method, 0},
{"(Value).Seq", Method, 23},
{"(Value).Seq2", Method, 23},
{"(Value).Set", Method, 0}, {"(Value).Set", Method, 0},
{"(Value).SetBool", Method, 0}, {"(Value).SetBool", Method, 0},
{"(Value).SetBytes", Method, 0}, {"(Value).SetBytes", Method, 0},
@ -9314,6 +9381,7 @@ var PackageSymbols = map[string][]Symbol{
{"SelectSend", Const, 1}, {"SelectSend", Const, 1},
{"SendDir", Const, 0}, {"SendDir", Const, 0},
{"Slice", Const, 0}, {"Slice", Const, 0},
{"SliceAt", Func, 23},
{"SliceHeader", Type, 0}, {"SliceHeader", Type, 0},
{"SliceHeader.Cap", Field, 0}, {"SliceHeader.Cap", Field, 0},
{"SliceHeader.Data", Field, 0}, {"SliceHeader.Data", Field, 0},
@ -9655,6 +9723,7 @@ var PackageSymbols = map[string][]Symbol{
{"BuildSetting", Type, 18}, {"BuildSetting", Type, 18},
{"BuildSetting.Key", Field, 18}, {"BuildSetting.Key", Field, 18},
{"BuildSetting.Value", Field, 18}, {"BuildSetting.Value", Field, 18},
{"CrashOptions", Type, 23},
{"FreeOSMemory", Func, 1}, {"FreeOSMemory", Func, 1},
{"GCStats", Type, 1}, {"GCStats", Type, 1},
{"GCStats.LastGC", Field, 1}, {"GCStats.LastGC", Field, 1},
@ -9672,6 +9741,7 @@ var PackageSymbols = map[string][]Symbol{
{"PrintStack", Func, 0}, {"PrintStack", Func, 0},
{"ReadBuildInfo", Func, 12}, {"ReadBuildInfo", Func, 12},
{"ReadGCStats", Func, 1}, {"ReadGCStats", Func, 1},
{"SetCrashOutput", Func, 23},
{"SetGCPercent", Func, 1}, {"SetGCPercent", Func, 1},
{"SetMaxStack", Func, 2}, {"SetMaxStack", Func, 2},
{"SetMaxThreads", Func, 2}, {"SetMaxThreads", Func, 2},
@ -9742,10 +9812,15 @@ var PackageSymbols = map[string][]Symbol{
{"WithRegion", Func, 11}, {"WithRegion", Func, 11},
}, },
"slices": { "slices": {
{"All", Func, 23},
{"AppendSeq", Func, 23},
{"Backward", Func, 23},
{"BinarySearch", Func, 21}, {"BinarySearch", Func, 21},
{"BinarySearchFunc", Func, 21}, {"BinarySearchFunc", Func, 21},
{"Chunk", Func, 23},
{"Clip", Func, 21}, {"Clip", Func, 21},
{"Clone", Func, 21}, {"Clone", Func, 21},
{"Collect", Func, 23},
{"Compact", Func, 21}, {"Compact", Func, 21},
{"CompactFunc", Func, 21}, {"CompactFunc", Func, 21},
{"Compare", Func, 21}, {"Compare", Func, 21},
@ -9767,11 +9842,16 @@ var PackageSymbols = map[string][]Symbol{
{"MaxFunc", Func, 21}, {"MaxFunc", Func, 21},
{"Min", Func, 21}, {"Min", Func, 21},
{"MinFunc", Func, 21}, {"MinFunc", Func, 21},
{"Repeat", Func, 23},
{"Replace", Func, 21}, {"Replace", Func, 21},
{"Reverse", Func, 21}, {"Reverse", Func, 21},
{"Sort", Func, 21}, {"Sort", Func, 21},
{"SortFunc", Func, 21}, {"SortFunc", Func, 21},
{"SortStableFunc", Func, 21}, {"SortStableFunc", Func, 21},
{"Sorted", Func, 23},
{"SortedFunc", Func, 23},
{"SortedStableFunc", Func, 23},
{"Values", Func, 23},
}, },
"sort": { "sort": {
{"(Float64Slice).Len", Method, 0}, {"(Float64Slice).Len", Method, 0},
@ -9936,10 +10016,14 @@ var PackageSymbols = map[string][]Symbol{
{"TrimSpace", Func, 0}, {"TrimSpace", Func, 0},
{"TrimSuffix", Func, 1}, {"TrimSuffix", Func, 1},
}, },
"structs": {
{"HostLayout", Type, 23},
},
"sync": { "sync": {
{"(*Cond).Broadcast", Method, 0}, {"(*Cond).Broadcast", Method, 0},
{"(*Cond).Signal", Method, 0}, {"(*Cond).Signal", Method, 0},
{"(*Cond).Wait", Method, 0}, {"(*Cond).Wait", Method, 0},
{"(*Map).Clear", Method, 23},
{"(*Map).CompareAndDelete", Method, 20}, {"(*Map).CompareAndDelete", Method, 20},
{"(*Map).CompareAndSwap", Method, 20}, {"(*Map).CompareAndSwap", Method, 20},
{"(*Map).Delete", Method, 9}, {"(*Map).Delete", Method, 9},
@ -9986,13 +10070,17 @@ var PackageSymbols = map[string][]Symbol{
{"(*Bool).Store", Method, 19}, {"(*Bool).Store", Method, 19},
{"(*Bool).Swap", Method, 19}, {"(*Bool).Swap", Method, 19},
{"(*Int32).Add", Method, 19}, {"(*Int32).Add", Method, 19},
{"(*Int32).And", Method, 23},
{"(*Int32).CompareAndSwap", Method, 19}, {"(*Int32).CompareAndSwap", Method, 19},
{"(*Int32).Load", Method, 19}, {"(*Int32).Load", Method, 19},
{"(*Int32).Or", Method, 23},
{"(*Int32).Store", Method, 19}, {"(*Int32).Store", Method, 19},
{"(*Int32).Swap", Method, 19}, {"(*Int32).Swap", Method, 19},
{"(*Int64).Add", Method, 19}, {"(*Int64).Add", Method, 19},
{"(*Int64).And", Method, 23},
{"(*Int64).CompareAndSwap", Method, 19}, {"(*Int64).CompareAndSwap", Method, 19},
{"(*Int64).Load", Method, 19}, {"(*Int64).Load", Method, 19},
{"(*Int64).Or", Method, 23},
{"(*Int64).Store", Method, 19}, {"(*Int64).Store", Method, 19},
{"(*Int64).Swap", Method, 19}, {"(*Int64).Swap", Method, 19},
{"(*Pointer).CompareAndSwap", Method, 19}, {"(*Pointer).CompareAndSwap", Method, 19},
@ -10000,18 +10088,24 @@ var PackageSymbols = map[string][]Symbol{
{"(*Pointer).Store", Method, 19}, {"(*Pointer).Store", Method, 19},
{"(*Pointer).Swap", Method, 19}, {"(*Pointer).Swap", Method, 19},
{"(*Uint32).Add", Method, 19}, {"(*Uint32).Add", Method, 19},
{"(*Uint32).And", Method, 23},
{"(*Uint32).CompareAndSwap", Method, 19}, {"(*Uint32).CompareAndSwap", Method, 19},
{"(*Uint32).Load", Method, 19}, {"(*Uint32).Load", Method, 19},
{"(*Uint32).Or", Method, 23},
{"(*Uint32).Store", Method, 19}, {"(*Uint32).Store", Method, 19},
{"(*Uint32).Swap", Method, 19}, {"(*Uint32).Swap", Method, 19},
{"(*Uint64).Add", Method, 19}, {"(*Uint64).Add", Method, 19},
{"(*Uint64).And", Method, 23},
{"(*Uint64).CompareAndSwap", Method, 19}, {"(*Uint64).CompareAndSwap", Method, 19},
{"(*Uint64).Load", Method, 19}, {"(*Uint64).Load", Method, 19},
{"(*Uint64).Or", Method, 23},
{"(*Uint64).Store", Method, 19}, {"(*Uint64).Store", Method, 19},
{"(*Uint64).Swap", Method, 19}, {"(*Uint64).Swap", Method, 19},
{"(*Uintptr).Add", Method, 19}, {"(*Uintptr).Add", Method, 19},
{"(*Uintptr).And", Method, 23},
{"(*Uintptr).CompareAndSwap", Method, 19}, {"(*Uintptr).CompareAndSwap", Method, 19},
{"(*Uintptr).Load", Method, 19}, {"(*Uintptr).Load", Method, 19},
{"(*Uintptr).Or", Method, 23},
{"(*Uintptr).Store", Method, 19}, {"(*Uintptr).Store", Method, 19},
{"(*Uintptr).Swap", Method, 19}, {"(*Uintptr).Swap", Method, 19},
{"(*Value).CompareAndSwap", Method, 17}, {"(*Value).CompareAndSwap", Method, 17},
@ -10023,6 +10117,11 @@ var PackageSymbols = map[string][]Symbol{
{"AddUint32", Func, 0}, {"AddUint32", Func, 0},
{"AddUint64", Func, 0}, {"AddUint64", Func, 0},
{"AddUintptr", Func, 0}, {"AddUintptr", Func, 0},
{"AndInt32", Func, 23},
{"AndInt64", Func, 23},
{"AndUint32", Func, 23},
{"AndUint64", Func, 23},
{"AndUintptr", Func, 23},
{"Bool", Type, 19}, {"Bool", Type, 19},
{"CompareAndSwapInt32", Func, 0}, {"CompareAndSwapInt32", Func, 0},
{"CompareAndSwapInt64", Func, 0}, {"CompareAndSwapInt64", Func, 0},
@ -10038,6 +10137,11 @@ var PackageSymbols = map[string][]Symbol{
{"LoadUint32", Func, 0}, {"LoadUint32", Func, 0},
{"LoadUint64", Func, 0}, {"LoadUint64", Func, 0},
{"LoadUintptr", Func, 0}, {"LoadUintptr", Func, 0},
{"OrInt32", Func, 23},
{"OrInt64", Func, 23},
{"OrUint32", Func, 23},
{"OrUint64", Func, 23},
{"OrUintptr", Func, 23},
{"Pointer", Type, 19}, {"Pointer", Type, 19},
{"StoreInt32", Func, 0}, {"StoreInt32", Func, 0},
{"StoreInt64", Func, 0}, {"StoreInt64", Func, 0},
@ -16200,6 +16304,7 @@ var PackageSymbols = map[string][]Symbol{
{"WSAEACCES", Const, 2}, {"WSAEACCES", Const, 2},
{"WSAECONNABORTED", Const, 9}, {"WSAECONNABORTED", Const, 9},
{"WSAECONNRESET", Const, 3}, {"WSAECONNRESET", Const, 3},
{"WSAENOPROTOOPT", Const, 23},
{"WSAEnumProtocols", Func, 2}, {"WSAEnumProtocols", Func, 2},
{"WSAID_CONNECTEX", Var, 1}, {"WSAID_CONNECTEX", Var, 1},
{"WSAIoctl", Func, 0}, {"WSAIoctl", Func, 0},
@ -17284,6 +17389,7 @@ var PackageSymbols = map[string][]Symbol{
{"Encode", Func, 0}, {"Encode", Func, 0},
{"EncodeRune", Func, 0}, {"EncodeRune", Func, 0},
{"IsSurrogate", Func, 0}, {"IsSurrogate", Func, 0},
{"RuneLen", Func, 23},
}, },
"unicode/utf8": { "unicode/utf8": {
{"AppendRune", Func, 18}, {"AppendRune", Func, 18},
@ -17306,6 +17412,11 @@ var PackageSymbols = map[string][]Symbol{
{"ValidRune", Func, 1}, {"ValidRune", Func, 1},
{"ValidString", Func, 0}, {"ValidString", Func, 0},
}, },
"unique": {
{"(Handle).Value", Method, 23},
{"Handle", Type, 23},
{"Make", Func, 23},
},
"unsafe": { "unsafe": {
{"Add", Func, 0}, {"Add", Func, 0},
{"Alignof", Func, 0}, {"Alignof", Func, 0},

View File

@ -10,7 +10,7 @@ RPC framework that puts mobile and HTTP/2 first. For more information see the
## Prerequisites ## Prerequisites
- **[Go][]**: any one of the **three latest major** [releases][go-releases]. - **[Go][]**: any one of the **two latest major** [releases][go-releases].
## Installation ## Installation

View File

@ -16,25 +16,35 @@
* *
*/ */
package grpc // Package pickfirst contains the pick_first load balancing policy.
package pickfirst
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"math/rand"
"google.golang.org/grpc/balancer" "google.golang.org/grpc/balancer"
"google.golang.org/grpc/connectivity" "google.golang.org/grpc/connectivity"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/internal"
internalgrpclog "google.golang.org/grpc/internal/grpclog" internalgrpclog "google.golang.org/grpc/internal/grpclog"
"google.golang.org/grpc/internal/grpcrand"
"google.golang.org/grpc/internal/pretty" "google.golang.org/grpc/internal/pretty"
"google.golang.org/grpc/resolver" "google.golang.org/grpc/resolver"
"google.golang.org/grpc/serviceconfig" "google.golang.org/grpc/serviceconfig"
) )
func init() {
balancer.Register(pickfirstBuilder{})
internal.ShuffleAddressListForTesting = func(n int, swap func(i, j int)) { rand.Shuffle(n, swap) }
}
var logger = grpclog.Component("pick-first-lb")
const ( const (
// PickFirstBalancerName is the name of the pick_first balancer. // Name is the name of the pick_first balancer.
PickFirstBalancerName = "pick_first" Name = "pick_first"
logPrefix = "[pick-first-lb %p] " logPrefix = "[pick-first-lb %p] "
) )
@ -47,7 +57,7 @@ func (pickfirstBuilder) Build(cc balancer.ClientConn, opt balancer.BuildOptions)
} }
func (pickfirstBuilder) Name() string { func (pickfirstBuilder) Name() string {
return PickFirstBalancerName return Name
} }
type pfConfig struct { type pfConfig struct {
@ -93,6 +103,12 @@ func (b *pickfirstBalancer) ResolverError(err error) {
}) })
} }
type Shuffler interface {
ShuffleAddressListForTesting(n int, swap func(i, j int))
}
func ShuffleAddressListForTesting(n int, swap func(i, j int)) { rand.Shuffle(n, swap) }
func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState) error { func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState) error {
if len(state.ResolverState.Addresses) == 0 && len(state.ResolverState.Endpoints) == 0 { if len(state.ResolverState.Addresses) == 0 && len(state.ResolverState.Endpoints) == 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
@ -124,7 +140,7 @@ func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState
// within each endpoint. - A61 // within each endpoint. - A61
if cfg.ShuffleAddressList { if cfg.ShuffleAddressList {
endpoints = append([]resolver.Endpoint{}, endpoints...) endpoints = append([]resolver.Endpoint{}, endpoints...)
grpcrand.Shuffle(len(endpoints), func(i, j int) { endpoints[i], endpoints[j] = endpoints[j], endpoints[i] }) internal.ShuffleAddressListForTesting.(func(int, func(int, int)))(len(endpoints), func(i, j int) { endpoints[i], endpoints[j] = endpoints[j], endpoints[i] })
} }
// "Flatten the list by concatenating the ordered list of addresses for each // "Flatten the list by concatenating the ordered list of addresses for each
@ -145,7 +161,7 @@ func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState
addrs = state.ResolverState.Addresses addrs = state.ResolverState.Addresses
if cfg.ShuffleAddressList { if cfg.ShuffleAddressList {
addrs = append([]resolver.Address{}, addrs...) addrs = append([]resolver.Address{}, addrs...)
grpcrand.Shuffle(len(addrs), func(i, j int) { addrs[i], addrs[j] = addrs[j], addrs[i] }) rand.Shuffle(len(addrs), func(i, j int) { addrs[i], addrs[j] = addrs[j], addrs[i] })
} }
} }

View File

@ -22,12 +22,12 @@
package roundrobin package roundrobin
import ( import (
"math/rand"
"sync/atomic" "sync/atomic"
"google.golang.org/grpc/balancer" "google.golang.org/grpc/balancer"
"google.golang.org/grpc/balancer/base" "google.golang.org/grpc/balancer/base"
"google.golang.org/grpc/grpclog" "google.golang.org/grpc/grpclog"
"google.golang.org/grpc/internal/grpcrand"
) )
// Name is the name of round_robin balancer. // Name is the name of round_robin balancer.
@ -60,7 +60,7 @@ func (*rrPickerBuilder) Build(info base.PickerBuildInfo) balancer.Picker {
// Start at a random index, as the same RR balancer rebuilds a new // Start at a random index, as the same RR balancer rebuilds a new
// picker when SubConn states change, and we don't want to apply excess // picker when SubConn states change, and we don't want to apply excess
// load to the first server in the list. // load to the first server in the list.
next: uint32(grpcrand.Intn(len(scs))), next: uint32(rand.Intn(len(scs))),
} }
} }

View File

@ -198,6 +198,10 @@ func (ccb *ccBalancerWrapper) UpdateAddresses(sc balancer.SubConn, addrs []resol
func (ccb *ccBalancerWrapper) UpdateState(s balancer.State) { func (ccb *ccBalancerWrapper) UpdateState(s balancer.State) {
ccb.cc.mu.Lock() ccb.cc.mu.Lock()
defer ccb.cc.mu.Unlock() defer ccb.cc.mu.Unlock()
if ccb.cc.conns == nil {
// The CC has been closed; ignore this update.
return
}
ccb.mu.Lock() ccb.mu.Lock()
if ccb.closed { if ccb.closed {

View File

@ -18,7 +18,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.33.0 // protoc-gen-go v1.34.1
// protoc v4.25.2 // protoc v4.25.2
// source: grpc/binlog/v1/binarylog.proto // source: grpc/binlog/v1/binarylog.proto

View File

@ -31,6 +31,7 @@ import (
"google.golang.org/grpc/balancer" "google.golang.org/grpc/balancer"
"google.golang.org/grpc/balancer/base" "google.golang.org/grpc/balancer/base"
"google.golang.org/grpc/balancer/pickfirst"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/connectivity" "google.golang.org/grpc/connectivity"
"google.golang.org/grpc/internal" "google.golang.org/grpc/internal"
@ -72,6 +73,8 @@ var (
// invalidDefaultServiceConfigErrPrefix is used to prefix the json parsing error for the default // invalidDefaultServiceConfigErrPrefix is used to prefix the json parsing error for the default
// service config. // service config.
invalidDefaultServiceConfigErrPrefix = "grpc: the provided default service config is invalid" invalidDefaultServiceConfigErrPrefix = "grpc: the provided default service config is invalid"
// PickFirstBalancerName is the name of the pick_first balancer.
PickFirstBalancerName = pickfirst.Name
) )
// The following errors are returned from Dial and DialContext // The following errors are returned from Dial and DialContext
@ -152,6 +155,16 @@ func NewClient(target string, opts ...DialOption) (conn *ClientConn, err error)
for _, opt := range opts { for _, opt := range opts {
opt.apply(&cc.dopts) opt.apply(&cc.dopts)
} }
// Determine the resolver to use.
if err := cc.initParsedTargetAndResolverBuilder(); err != nil {
return nil, err
}
for _, opt := range globalPerTargetDialOptions {
opt.DialOptionForTarget(cc.parsedTarget.URL).apply(&cc.dopts)
}
chainUnaryClientInterceptors(cc) chainUnaryClientInterceptors(cc)
chainStreamClientInterceptors(cc) chainStreamClientInterceptors(cc)
@ -160,7 +173,7 @@ func NewClient(target string, opts ...DialOption) (conn *ClientConn, err error)
} }
if cc.dopts.defaultServiceConfigRawJSON != nil { if cc.dopts.defaultServiceConfigRawJSON != nil {
scpr := parseServiceConfig(*cc.dopts.defaultServiceConfigRawJSON) scpr := parseServiceConfig(*cc.dopts.defaultServiceConfigRawJSON, cc.dopts.maxCallAttempts)
if scpr.Err != nil { if scpr.Err != nil {
return nil, fmt.Errorf("%s: %v", invalidDefaultServiceConfigErrPrefix, scpr.Err) return nil, fmt.Errorf("%s: %v", invalidDefaultServiceConfigErrPrefix, scpr.Err)
} }
@ -168,24 +181,15 @@ func NewClient(target string, opts ...DialOption) (conn *ClientConn, err error)
} }
cc.mkp = cc.dopts.copts.KeepaliveParams cc.mkp = cc.dopts.copts.KeepaliveParams
// Register ClientConn with channelz. if err = cc.initAuthority(); err != nil {
return nil, err
}
// Register ClientConn with channelz. Note that this is only done after
// channel creation cannot fail.
cc.channelzRegistration(target) cc.channelzRegistration(target)
channelz.Infof(logger, cc.channelz, "parsed dial target is: %#v", cc.parsedTarget)
// TODO: Ideally it should be impossible to error from this function after channelz.Infof(logger, cc.channelz, "Channel authority set to %q", cc.authority)
// channelz registration. This will require removing some channelz logs
// from the following functions that can error. Errors can be returned to
// the user, and successful logs can be emitted here, after the checks have
// passed and channelz is subsequently registered.
// Determine the resolver to use.
if err := cc.parseTargetAndFindResolver(); err != nil {
channelz.RemoveEntry(cc.channelz.ID)
return nil, err
}
if err = cc.determineAuthority(); err != nil {
channelz.RemoveEntry(cc.channelz.ID)
return nil, err
}
cc.csMgr = newConnectivityStateManager(cc.ctx, cc.channelz) cc.csMgr = newConnectivityStateManager(cc.ctx, cc.channelz)
cc.pickerWrapper = newPickerWrapper(cc.dopts.copts.StatsHandlers) cc.pickerWrapper = newPickerWrapper(cc.dopts.copts.StatsHandlers)
@ -587,11 +591,11 @@ type ClientConn struct {
// The following are initialized at dial time, and are read-only after that. // The following are initialized at dial time, and are read-only after that.
target string // User's dial target. target string // User's dial target.
parsedTarget resolver.Target // See parseTargetAndFindResolver(). parsedTarget resolver.Target // See initParsedTargetAndResolverBuilder().
authority string // See determineAuthority(). authority string // See initAuthority().
dopts dialOptions // Default and user specified dial options. dopts dialOptions // Default and user specified dial options.
channelz *channelz.Channel // Channelz object. channelz *channelz.Channel // Channelz object.
resolverBuilder resolver.Builder // See parseTargetAndFindResolver(). resolverBuilder resolver.Builder // See initParsedTargetAndResolverBuilder().
idlenessMgr *idle.Manager idlenessMgr *idle.Manager
// The following provide their own synchronization, and therefore don't // The following provide their own synchronization, and therefore don't
@ -692,8 +696,7 @@ func (cc *ClientConn) waitForResolvedAddrs(ctx context.Context) error {
var emptyServiceConfig *ServiceConfig var emptyServiceConfig *ServiceConfig
func init() { func init() {
balancer.Register(pickfirstBuilder{}) cfg := parseServiceConfig("{}", defaultMaxCallAttempts)
cfg := parseServiceConfig("{}")
if cfg.Err != nil { if cfg.Err != nil {
panic(fmt.Sprintf("impossible error parsing empty service config: %v", cfg.Err)) panic(fmt.Sprintf("impossible error parsing empty service config: %v", cfg.Err))
} }
@ -1673,22 +1676,19 @@ func (cc *ClientConn) connectionError() error {
return cc.lastConnectionError return cc.lastConnectionError
} }
// parseTargetAndFindResolver parses the user's dial target and stores the // initParsedTargetAndResolverBuilder parses the user's dial target and stores
// parsed target in `cc.parsedTarget`. // the parsed target in `cc.parsedTarget`.
// //
// The resolver to use is determined based on the scheme in the parsed target // The resolver to use is determined based on the scheme in the parsed target
// and the same is stored in `cc.resolverBuilder`. // and the same is stored in `cc.resolverBuilder`.
// //
// Doesn't grab cc.mu as this method is expected to be called only at Dial time. // Doesn't grab cc.mu as this method is expected to be called only at Dial time.
func (cc *ClientConn) parseTargetAndFindResolver() error { func (cc *ClientConn) initParsedTargetAndResolverBuilder() error {
channelz.Infof(logger, cc.channelz, "original dial target is: %q", cc.target) logger.Infof("original dial target is: %q", cc.target)
var rb resolver.Builder var rb resolver.Builder
parsedTarget, err := parseTarget(cc.target) parsedTarget, err := parseTarget(cc.target)
if err != nil { if err == nil {
channelz.Infof(logger, cc.channelz, "dial target %q parse failed: %v", cc.target, err)
} else {
channelz.Infof(logger, cc.channelz, "parsed dial target is: %#v", parsedTarget)
rb = cc.getResolver(parsedTarget.URL.Scheme) rb = cc.getResolver(parsedTarget.URL.Scheme)
if rb != nil { if rb != nil {
cc.parsedTarget = parsedTarget cc.parsedTarget = parsedTarget
@ -1707,15 +1707,12 @@ func (cc *ClientConn) parseTargetAndFindResolver() error {
defScheme = resolver.GetDefaultScheme() defScheme = resolver.GetDefaultScheme()
} }
channelz.Infof(logger, cc.channelz, "fallback to scheme %q", defScheme)
canonicalTarget := defScheme + ":///" + cc.target canonicalTarget := defScheme + ":///" + cc.target
parsedTarget, err = parseTarget(canonicalTarget) parsedTarget, err = parseTarget(canonicalTarget)
if err != nil { if err != nil {
channelz.Infof(logger, cc.channelz, "dial target %q parse failed: %v", canonicalTarget, err)
return err return err
} }
channelz.Infof(logger, cc.channelz, "parsed dial target is: %+v", parsedTarget)
rb = cc.getResolver(parsedTarget.URL.Scheme) rb = cc.getResolver(parsedTarget.URL.Scheme)
if rb == nil { if rb == nil {
return fmt.Errorf("could not get resolver for default scheme: %q", parsedTarget.URL.Scheme) return fmt.Errorf("could not get resolver for default scheme: %q", parsedTarget.URL.Scheme)
@ -1805,7 +1802,7 @@ func encodeAuthority(authority string) string {
// credentials do not match the authority configured through the dial option. // credentials do not match the authority configured through the dial option.
// //
// Doesn't grab cc.mu as this method is expected to be called only at Dial time. // Doesn't grab cc.mu as this method is expected to be called only at Dial time.
func (cc *ClientConn) determineAuthority() error { func (cc *ClientConn) initAuthority() error {
dopts := cc.dopts dopts := cc.dopts
// Historically, we had two options for users to specify the serverName or // Historically, we had two options for users to specify the serverName or
// authority for a channel. One was through the transport credentials // authority for a channel. One was through the transport credentials
@ -1838,6 +1835,5 @@ func (cc *ClientConn) determineAuthority() error {
} else { } else {
cc.authority = encodeAuthority(endpoint) cc.authority = encodeAuthority(endpoint)
} }
channelz.Infof(logger, cc.channelz, "Channel authority set to %q", cc.authority)
return nil return nil
} }

View File

@ -27,9 +27,13 @@ import (
"net/url" "net/url"
"os" "os"
"google.golang.org/grpc/grpclog"
credinternal "google.golang.org/grpc/internal/credentials" credinternal "google.golang.org/grpc/internal/credentials"
"google.golang.org/grpc/internal/envconfig"
) )
var logger = grpclog.Component("credentials")
// TLSInfo contains the auth information for a TLS authenticated connection. // TLSInfo contains the auth information for a TLS authenticated connection.
// It implements the AuthInfo interface. // It implements the AuthInfo interface.
type TLSInfo struct { type TLSInfo struct {
@ -112,6 +116,22 @@ func (c *tlsCreds) ClientHandshake(ctx context.Context, authority string, rawCon
conn.Close() conn.Close()
return nil, nil, ctx.Err() return nil, nil, ctx.Err()
} }
// The negotiated protocol can be either of the following:
// 1. h2: When the server supports ALPN. Only HTTP/2 can be negotiated since
// it is the only protocol advertised by the client during the handshake.
// The tls library ensures that the server chooses a protocol advertised
// by the client.
// 2. "" (empty string): If the server doesn't support ALPN. ALPN is a requirement
// for using HTTP/2 over TLS. We can terminate the connection immediately.
np := conn.ConnectionState().NegotiatedProtocol
if np == "" {
if envconfig.EnforceALPNEnabled {
conn.Close()
return nil, nil, fmt.Errorf("credentials: cannot check peer: missing selected ALPN property")
}
logger.Warningf("Allowing TLS connection to server %q with ALPN disabled. TLS connections to servers with ALPN disabled will be disallowed in future grpc-go releases", cfg.ServerName)
}
tlsInfo := TLSInfo{ tlsInfo := TLSInfo{
State: conn.ConnectionState(), State: conn.ConnectionState(),
CommonAuthInfo: CommonAuthInfo{ CommonAuthInfo: CommonAuthInfo{
@ -131,8 +151,20 @@ func (c *tlsCreds) ServerHandshake(rawConn net.Conn) (net.Conn, AuthInfo, error)
conn.Close() conn.Close()
return nil, nil, err return nil, nil, err
} }
cs := conn.ConnectionState()
// The negotiated application protocol can be empty only if the client doesn't
// support ALPN. In such cases, we can close the connection since ALPN is required
// for using HTTP/2 over TLS.
if cs.NegotiatedProtocol == "" {
if envconfig.EnforceALPNEnabled {
conn.Close()
return nil, nil, fmt.Errorf("credentials: cannot check peer: missing selected ALPN property")
} else if logger.V(2) {
logger.Info("Allowing TLS connection from client with ALPN disabled. TLS connections with ALPN disabled will be disallowed in future grpc-go releases")
}
}
tlsInfo := TLSInfo{ tlsInfo := TLSInfo{
State: conn.ConnectionState(), State: cs,
CommonAuthInfo: CommonAuthInfo{ CommonAuthInfo: CommonAuthInfo{
SecurityLevel: PrivacyAndIntegrity, SecurityLevel: PrivacyAndIntegrity,
}, },

View File

@ -21,6 +21,7 @@ package grpc
import ( import (
"context" "context"
"net" "net"
"net/url"
"time" "time"
"google.golang.org/grpc/backoff" "google.golang.org/grpc/backoff"
@ -36,6 +37,11 @@ import (
"google.golang.org/grpc/stats" "google.golang.org/grpc/stats"
) )
const (
// https://github.com/grpc/proposal/blob/master/A6-client-retries.md#limits-on-retries-and-hedges
defaultMaxCallAttempts = 5
)
func init() { func init() {
internal.AddGlobalDialOptions = func(opt ...DialOption) { internal.AddGlobalDialOptions = func(opt ...DialOption) {
globalDialOptions = append(globalDialOptions, opt...) globalDialOptions = append(globalDialOptions, opt...)
@ -43,6 +49,14 @@ func init() {
internal.ClearGlobalDialOptions = func() { internal.ClearGlobalDialOptions = func() {
globalDialOptions = nil globalDialOptions = nil
} }
internal.AddGlobalPerTargetDialOptions = func(opt any) {
if ptdo, ok := opt.(perTargetDialOption); ok {
globalPerTargetDialOptions = append(globalPerTargetDialOptions, ptdo)
}
}
internal.ClearGlobalPerTargetDialOptions = func() {
globalPerTargetDialOptions = nil
}
internal.WithBinaryLogger = withBinaryLogger internal.WithBinaryLogger = withBinaryLogger
internal.JoinDialOptions = newJoinDialOption internal.JoinDialOptions = newJoinDialOption
internal.DisableGlobalDialOptions = newDisableGlobalDialOptions internal.DisableGlobalDialOptions = newDisableGlobalDialOptions
@ -80,6 +94,7 @@ type dialOptions struct {
idleTimeout time.Duration idleTimeout time.Duration
recvBufferPool SharedBufferPool recvBufferPool SharedBufferPool
defaultScheme string defaultScheme string
maxCallAttempts int
} }
// DialOption configures how we set up the connection. // DialOption configures how we set up the connection.
@ -89,6 +104,19 @@ type DialOption interface {
var globalDialOptions []DialOption var globalDialOptions []DialOption
// perTargetDialOption takes a parsed target and returns a dial option to apply.
//
// This gets called after NewClient() parses the target, and allows per target
// configuration set through a returned DialOption. The DialOption will not take
// effect if specifies a resolver builder, as that Dial Option is factored in
// while parsing target.
type perTargetDialOption interface {
// DialOption returns a Dial Option to apply.
DialOptionForTarget(parsedTarget url.URL) DialOption
}
var globalPerTargetDialOptions []perTargetDialOption
// 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.
// //
@ -655,6 +683,7 @@ func defaultDialOptions() dialOptions {
idleTimeout: 30 * time.Minute, idleTimeout: 30 * time.Minute,
recvBufferPool: nopBufferPool{}, recvBufferPool: nopBufferPool{},
defaultScheme: "dns", defaultScheme: "dns",
maxCallAttempts: defaultMaxCallAttempts,
} }
} }
@ -712,6 +741,23 @@ func WithIdleTimeout(d time.Duration) DialOption {
}) })
} }
// WithMaxCallAttempts returns a DialOption that configures the maximum number
// of attempts per call (including retries and hedging) using the channel.
// Service owners may specify a higher value for these parameters, but higher
// values will be treated as equal to the maximum value by the client
// implementation. This mitigates security concerns related to the service
// config being transferred to the client via DNS.
//
// A value of 5 will be used if this dial option is not set or n < 2.
func WithMaxCallAttempts(n int) DialOption {
return newFuncDialOption(func(o *dialOptions) {
if n < 2 {
n = defaultMaxCallAttempts
}
o.maxCallAttempts = n
})
}
// WithRecvBufferPool returns a DialOption that configures the ClientConn // WithRecvBufferPool returns a DialOption that configures the ClientConn
// to use the provided shared buffer pool for parsing incoming messages. Depending // to use the provided shared buffer pool for parsing incoming messages. Depending
// on the application's workload, this could result in reduced memory allocation. // on the application's workload, this could result in reduced memory allocation.

View File

@ -17,7 +17,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.33.0 // protoc-gen-go v1.34.1
// protoc v4.25.2 // protoc v4.25.2
// source: grpc/health/v1/health.proto // source: grpc/health/v1/health.proto

View File

@ -17,7 +17,7 @@
// 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.3.0 // - protoc-gen-go-grpc v1.4.0
// - protoc v4.25.2 // - protoc v4.25.2
// source: grpc/health/v1/health.proto // source: grpc/health/v1/health.proto
@ -43,6 +43,10 @@ const (
// 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.
//
// Health is gRPC's mechanism for checking whether a server is able to handle
// RPCs. Its semantics are documented in
// https://github.com/grpc/grpc/blob/master/doc/health-checking.md.
type HealthClient interface { type HealthClient interface {
// Check gets the health of the specified service. If the requested service // Check gets the health of the specified service. If the requested service
// is unknown, the call will fail with status NOT_FOUND. If the caller does // is unknown, the call will fail with status NOT_FOUND. If the caller does
@ -126,6 +130,10 @@ func (x *healthWatchClient) Recv() (*HealthCheckResponse, error) {
// HealthServer is the server API for Health service. // HealthServer is the server API for Health service.
// All implementations should embed UnimplementedHealthServer // All implementations should embed UnimplementedHealthServer
// for forward compatibility // for forward compatibility
//
// Health is gRPC's mechanism for checking whether a server is able to handle
// RPCs. Its semantics are documented in
// https://github.com/grpc/grpc/blob/master/doc/health-checking.md.
type HealthServer interface { type HealthServer interface {
// Check gets the health of the specified service. If the requested service // Check gets the health of the specified service. If the requested service
// is unknown, the call will fail with status NOT_FOUND. If the caller does // is unknown, the call will fail with status NOT_FOUND. If the caller does

View File

@ -25,10 +25,10 @@ package backoff
import ( import (
"context" "context"
"errors" "errors"
"math/rand"
"time" "time"
grpcbackoff "google.golang.org/grpc/backoff" grpcbackoff "google.golang.org/grpc/backoff"
"google.golang.org/grpc/internal/grpcrand"
) )
// Strategy defines the methodology for backing off after a grpc connection // Strategy defines the methodology for backing off after a grpc connection
@ -67,7 +67,7 @@ func (bc Exponential) Backoff(retries int) time.Duration {
} }
// Randomize backoff delays so that if a cluster of requests start at // Randomize backoff delays so that if a cluster of requests start at
// the same time, they won't operate in lockstep. // the same time, they won't operate in lockstep.
backoff *= 1 + bc.Config.Jitter*(grpcrand.Float64()*2-1) backoff *= 1 + bc.Config.Jitter*(rand.Float64()*2-1)
if backoff < 0 { if backoff < 0 {
return 0 return 0
} }

View File

@ -40,6 +40,12 @@ var (
// ALTSMaxConcurrentHandshakes is the maximum number of concurrent ALTS // ALTSMaxConcurrentHandshakes is the maximum number of concurrent ALTS
// handshakes that can be performed. // handshakes that can be performed.
ALTSMaxConcurrentHandshakes = uint64FromEnv("GRPC_ALTS_MAX_CONCURRENT_HANDSHAKES", 100, 1, 100) ALTSMaxConcurrentHandshakes = uint64FromEnv("GRPC_ALTS_MAX_CONCURRENT_HANDSHAKES", 100, 1, 100)
// EnforceALPNEnabled is set if TLS connections to servers with ALPN disabled
// should be rejected. The HTTP/2 protocol requires ALPN to be enabled, this
// option is present for backward compatibility. This option may be overridden
// by setting the environment variable "GRPC_ENFORCE_ALPN_ENABLED" to "true"
// or "false".
EnforceALPNEnabled = boolFromEnv("GRPC_ENFORCE_ALPN_ENABLED", false)
) )
func boolFromEnv(envVar string, def bool) bool { func boolFromEnv(envVar string, def bool) bool {

View File

@ -1,100 +0,0 @@
//go:build !go1.21
// TODO: when this file is deleted (after Go 1.20 support is dropped), delete
// all of grpcrand and call the rand package directly.
/*
*
* Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
// Package grpcrand implements math/rand functions in a concurrent-safe way
// with a global random source, independent of math/rand's global source.
package grpcrand
import (
"math/rand"
"sync"
"time"
)
var (
r = rand.New(rand.NewSource(time.Now().UnixNano()))
mu sync.Mutex
)
// Int implements rand.Int on the grpcrand global source.
func Int() int {
mu.Lock()
defer mu.Unlock()
return r.Int()
}
// Int63n implements rand.Int63n on the grpcrand global source.
func Int63n(n int64) int64 {
mu.Lock()
defer mu.Unlock()
return r.Int63n(n)
}
// Intn implements rand.Intn on the grpcrand global source.
func Intn(n int) int {
mu.Lock()
defer mu.Unlock()
return r.Intn(n)
}
// Int31n implements rand.Int31n on the grpcrand global source.
func Int31n(n int32) int32 {
mu.Lock()
defer mu.Unlock()
return r.Int31n(n)
}
// Float64 implements rand.Float64 on the grpcrand global source.
func Float64() float64 {
mu.Lock()
defer mu.Unlock()
return r.Float64()
}
// Uint64 implements rand.Uint64 on the grpcrand global source.
func Uint64() uint64 {
mu.Lock()
defer mu.Unlock()
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)
}

View File

@ -1,73 +0,0 @@
//go:build go1.21
/*
*
* Copyright 2024 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
// Package grpcrand implements math/rand functions in a concurrent-safe way
// with a global random source, independent of math/rand's global source.
package grpcrand
import "math/rand"
// This implementation will be used for Go version 1.21 or newer.
// For older versions, the original implementation with mutex will be used.
// Int implements rand.Int on the grpcrand global source.
func Int() int {
return rand.Int()
}
// Int63n implements rand.Int63n on the grpcrand global source.
func Int63n(n int64) int64 {
return rand.Int63n(n)
}
// Intn implements rand.Intn on the grpcrand global source.
func Intn(n int) int {
return rand.Intn(n)
}
// Int31n implements rand.Int31n on the grpcrand global source.
func Int31n(n int32) int32 {
return rand.Int31n(n)
}
// Float64 implements rand.Float64 on the grpcrand global source.
func Float64() float64 {
return rand.Float64()
}
// Uint64 implements rand.Uint64 on the grpcrand global source.
func Uint64() uint64 {
return rand.Uint64()
}
// Uint32 implements rand.Uint32 on the grpcrand global source.
func Uint32() uint32 {
return rand.Uint32()
}
// ExpFloat64 implements rand.ExpFloat64 on the grpcrand global source.
func ExpFloat64() float64 {
return rand.ExpFloat64()
}
// Shuffle implements rand.Shuffle on the grpcrand global source.
var Shuffle = func(n int, f func(int, int)) {
rand.Shuffle(n, f)
}

View File

@ -106,6 +106,14 @@ var (
// This is used in the 1.0 release of gcp/observability, and thus must not be // This is used in the 1.0 release of gcp/observability, and thus must not be
// deleted or changed. // deleted or changed.
ClearGlobalDialOptions func() ClearGlobalDialOptions func()
// AddGlobalPerTargetDialOptions adds a PerTargetDialOption that will be
// configured for newly created ClientConns.
AddGlobalPerTargetDialOptions any // func (opt any)
// ClearGlobalPerTargetDialOptions clears the slice of global late apply
// dial options.
ClearGlobalPerTargetDialOptions 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 any // func(...grpc.DialOption) grpc.DialOption JoinDialOptions any // func(...grpc.DialOption) grpc.DialOption
@ -126,7 +134,8 @@ var (
// deleted or changed. // deleted or changed.
BinaryLogger any // func(binarylog.Logger) grpc.ServerOption BinaryLogger any // func(binarylog.Logger) grpc.ServerOption
// SubscribeToConnectivityStateChanges adds a grpcsync.Subscriber to a provided grpc.ClientConn // SubscribeToConnectivityStateChanges adds a grpcsync.Subscriber to a
// provided grpc.ClientConn.
SubscribeToConnectivityStateChanges any // func(*grpc.ClientConn, grpcsync.Subscriber) SubscribeToConnectivityStateChanges any // func(*grpc.ClientConn, grpcsync.Subscriber)
// NewXDSResolverWithConfigForTesting creates a new xds resolver builder using // NewXDSResolverWithConfigForTesting creates a new xds resolver builder using
@ -184,25 +193,25 @@ var (
ChannelzTurnOffForTesting func() ChannelzTurnOffForTesting func()
// TriggerXDSResourceNameNotFoundForTesting triggers the resource-not-found // TriggerXDSResourceNotFoundForTesting causes the provided xDS Client to
// error for a given resource type and name. This is usually triggered when // invoke resource-not-found error for the given resource type and name.
// the associated watch timer fires. For testing purposes, having this TriggerXDSResourceNotFoundForTesting any // func(xdsclient.XDSClient, xdsresource.Type, string) error
// function makes events more predictable than relying on timer events.
TriggerXDSResourceNameNotFoundForTesting any // func(func(xdsresource.Type, string), string, string) error
// TriggerXDSResourceNameNotFoundClient invokes the testing xDS Client // FromOutgoingContextRaw returns the un-merged, intermediary contents of
// singleton to invoke resource not found for a resource type name and // metadata.rawMD.
// resource name.
TriggerXDSResourceNameNotFoundClient any // func(string, string) error
// FromOutgoingContextRaw returns the un-merged, intermediary contents of metadata.rawMD.
FromOutgoingContextRaw any // func(context.Context) (metadata.MD, [][]string, bool) FromOutgoingContextRaw any // func(context.Context) (metadata.MD, [][]string, bool)
// UserSetDefaultScheme is set to true if the user has overridden the default resolver scheme. // UserSetDefaultScheme is set to true if the user has overridden the
// default resolver scheme.
UserSetDefaultScheme bool = false UserSetDefaultScheme bool = false
// ShuffleAddressListForTesting pseudo-randomizes the order of addresses. n
// is the number of elements. swap swaps the elements with indexes i and j.
ShuffleAddressListForTesting any // func(n int, swap func(i, j int))
) )
// 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.
// //
// The implementation is expected to create a health checking RPC stream by // The implementation is expected to create a health checking RPC stream by
// calling newStream(), watch for the health status of serviceName, and report // calling newStream(), watch for the health status of serviceName, and report

View File

@ -24,6 +24,7 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"math/rand"
"net" "net"
"os" "os"
"strconv" "strconv"
@ -35,7 +36,6 @@ import (
"google.golang.org/grpc/grpclog" "google.golang.org/grpc/grpclog"
"google.golang.org/grpc/internal/backoff" "google.golang.org/grpc/internal/backoff"
"google.golang.org/grpc/internal/envconfig" "google.golang.org/grpc/internal/envconfig"
"google.golang.org/grpc/internal/grpcrand"
"google.golang.org/grpc/internal/resolver/dns/internal" "google.golang.org/grpc/internal/resolver/dns/internal"
"google.golang.org/grpc/resolver" "google.golang.org/grpc/resolver"
"google.golang.org/grpc/serviceconfig" "google.golang.org/grpc/serviceconfig"
@ -63,6 +63,8 @@ var (
func init() { func init() {
resolver.Register(NewBuilder()) resolver.Register(NewBuilder())
internal.TimeAfterFunc = time.After internal.TimeAfterFunc = time.After
internal.TimeNowFunc = time.Now
internal.TimeUntilFunc = time.Until
internal.NewNetResolver = newNetResolver internal.NewNetResolver = newNetResolver
internal.AddressDialer = addressDialer internal.AddressDialer = addressDialer
} }
@ -209,12 +211,12 @@ func (d *dnsResolver) watcher() {
err = d.cc.UpdateState(*state) err = d.cc.UpdateState(*state)
} }
var waitTime time.Duration var nextResolutionTime time.Time
if err == nil { if err == nil {
// Success resolving, wait for the next ResolveNow. However, also wait 30 // Success resolving, wait for the next ResolveNow. However, also wait 30
// seconds at the very least to prevent constantly re-resolving. // seconds at the very least to prevent constantly re-resolving.
backoffIndex = 1 backoffIndex = 1
waitTime = MinResolutionInterval nextResolutionTime = internal.TimeNowFunc().Add(MinResolutionInterval)
select { select {
case <-d.ctx.Done(): case <-d.ctx.Done():
return return
@ -223,13 +225,13 @@ func (d *dnsResolver) watcher() {
} else { } else {
// Poll on an error found in DNS Resolver or an error received from // Poll on an error found in DNS Resolver or an error received from
// ClientConn. // ClientConn.
waitTime = backoff.DefaultExponential.Backoff(backoffIndex) nextResolutionTime = internal.TimeNowFunc().Add(backoff.DefaultExponential.Backoff(backoffIndex))
backoffIndex++ backoffIndex++
} }
select { select {
case <-d.ctx.Done(): case <-d.ctx.Done():
return return
case <-internal.TimeAfterFunc(waitTime): case <-internal.TimeAfterFunc(internal.TimeUntilFunc(nextResolutionTime)):
} }
} }
} }
@ -423,7 +425,7 @@ func chosenByPercentage(a *int) bool {
if a == nil { if a == nil {
return true return true
} }
return grpcrand.Intn(100)+1 <= *a return rand.Intn(100)+1 <= *a
} }
func canaryingSC(js string) string { func canaryingSC(js string) string {

View File

@ -56,6 +56,17 @@ var (
// blocked waiting for the duration to elapse. // blocked waiting for the duration to elapse.
TimeAfterFunc func(time.Duration) <-chan time.Time TimeAfterFunc func(time.Duration) <-chan time.Time
// TimeNowFunc is used by the DNS resolver to get the current time.
// In non-test code, this is implemented by time.Now. In test code,
// this can be used to control the current time for the resolver.
TimeNowFunc func() time.Time
// TimeUntilFunc is used by the DNS resolver to calculate the remaining
// wait time for re-resolution. In non-test code, this is implemented by
// time.Until. In test code, this can be used to control the remaining
// time for resolver to wait for re-resolution.
TimeUntilFunc func(time.Time) time.Duration
// NewNetResolver returns the net.Resolver instance for the given target. // NewNetResolver returns the net.Resolver instance for the given target.
NewNetResolver func(string) (NetResolver, error) NewNetResolver func(string) (NetResolver, error)

View File

@ -25,6 +25,7 @@ import (
"fmt" "fmt"
"io" "io"
"math" "math"
"math/rand"
"net" "net"
"net/http" "net/http"
"strconv" "strconv"
@ -43,7 +44,6 @@ import (
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials"
"google.golang.org/grpc/internal/channelz" "google.golang.org/grpc/internal/channelz"
"google.golang.org/grpc/internal/grpcrand"
"google.golang.org/grpc/internal/grpcsync" "google.golang.org/grpc/internal/grpcsync"
"google.golang.org/grpc/keepalive" "google.golang.org/grpc/keepalive"
"google.golang.org/grpc/metadata" "google.golang.org/grpc/metadata"
@ -1440,7 +1440,7 @@ func getJitter(v time.Duration) time.Duration {
} }
// Generate a jitter between +/- 10% of the value. // Generate a jitter between +/- 10% of the value.
r := int64(v / 10) r := int64(v / 10)
j := grpcrand.Int63n(2*r) - r j := rand.Int63n(2*r) - r
return time.Duration(j) return time.Duration(j)
} }

View File

@ -90,21 +90,6 @@ func Pairs(kv ...string) MD {
return md return md
} }
// String implements the Stringer interface for pretty-printing a MD.
// Ordering of the values is non-deterministic as it ranges over a map.
func (md MD) String() string {
var sb strings.Builder
fmt.Fprintf(&sb, "MD{")
for k, v := range md {
if sb.Len() > 3 {
fmt.Fprintf(&sb, ", ")
}
fmt.Fprintf(&sb, "%s=[%s]", k, strings.Join(v, ", "))
}
fmt.Fprintf(&sb, "}")
return sb.String()
}
// Len returns the number of items in md. // Len returns the number of items in md.
func (md MD) Len() int { func (md MD) Len() int {
return len(md) return len(md)

View File

@ -22,7 +22,7 @@ import (
"context" "context"
"fmt" "fmt"
"io" "io"
"sync" "sync/atomic"
"google.golang.org/grpc/balancer" "google.golang.org/grpc/balancer"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
@ -33,35 +33,43 @@ import (
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
) )
// pickerGeneration stores a picker and a channel used to signal that a picker
// newer than this one is available.
type pickerGeneration struct {
// picker is the picker produced by the LB policy. May be nil if a picker
// has never been produced.
picker balancer.Picker
// blockingCh is closed when the picker has been invalidated because there
// is a new one available.
blockingCh chan struct{}
}
// pickerWrapper is a wrapper of balancer.Picker. It blocks on certain pick // pickerWrapper is a wrapper of balancer.Picker. It blocks on certain pick
// actions and unblock when there's a picker update. // actions and unblock when there's a picker update.
type pickerWrapper struct { type pickerWrapper struct {
mu sync.Mutex // If pickerGen holds a nil pointer, the pickerWrapper is closed.
done bool pickerGen atomic.Pointer[pickerGeneration]
blockingCh chan struct{}
picker balancer.Picker
statsHandlers []stats.Handler // to record blocking picker calls statsHandlers []stats.Handler // to record blocking picker calls
} }
func newPickerWrapper(statsHandlers []stats.Handler) *pickerWrapper { func newPickerWrapper(statsHandlers []stats.Handler) *pickerWrapper {
return &pickerWrapper{ pw := &pickerWrapper{
blockingCh: make(chan struct{}),
statsHandlers: statsHandlers, statsHandlers: statsHandlers,
} }
pw.pickerGen.Store(&pickerGeneration{
blockingCh: make(chan struct{}),
})
return pw
} }
// updatePicker is called by UpdateBalancerState. It unblocks all blocked pick. // updatePicker is called by UpdateState calls from the LB policy. It
// unblocks all blocked pick.
func (pw *pickerWrapper) updatePicker(p balancer.Picker) { func (pw *pickerWrapper) updatePicker(p balancer.Picker) {
pw.mu.Lock() old := pw.pickerGen.Swap(&pickerGeneration{
if pw.done { picker: p,
pw.mu.Unlock() blockingCh: make(chan struct{}),
return })
} close(old.blockingCh)
pw.picker = p
// pw.blockingCh should never be nil.
close(pw.blockingCh)
pw.blockingCh = make(chan struct{})
pw.mu.Unlock()
} }
// doneChannelzWrapper performs the following: // doneChannelzWrapper performs the following:
@ -98,20 +106,17 @@ func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer.
var lastPickErr error var lastPickErr error
for { for {
pw.mu.Lock() pg := pw.pickerGen.Load()
if pw.done { if pg == nil {
pw.mu.Unlock()
return nil, balancer.PickResult{}, ErrClientConnClosing return nil, balancer.PickResult{}, ErrClientConnClosing
} }
if pg.picker == nil {
if pw.picker == nil { ch = pg.blockingCh
ch = pw.blockingCh
} }
if ch == pw.blockingCh { if ch == pg.blockingCh {
// This could happen when either: // This could happen when either:
// - pw.picker is nil (the previous if condition), or // - pw.picker is nil (the previous if condition), or
// - has called pick on the current picker. // - we have already called pick on the current picker.
pw.mu.Unlock()
select { select {
case <-ctx.Done(): case <-ctx.Done():
var errStr string var errStr string
@ -145,9 +150,8 @@ func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer.
} }
} }
ch = pw.blockingCh ch = pg.blockingCh
p := pw.picker p := pg.picker
pw.mu.Unlock()
pickResult, err := p.Pick(info) pickResult, err := p.Pick(info)
if err != nil { if err != nil {
@ -197,24 +201,15 @@ func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer.
} }
func (pw *pickerWrapper) close() { func (pw *pickerWrapper) close() {
pw.mu.Lock() old := pw.pickerGen.Swap(nil)
defer pw.mu.Unlock() close(old.blockingCh)
if pw.done {
return
}
pw.done = true
close(pw.blockingCh)
} }
// reset clears the pickerWrapper and prepares it for being used again when idle // reset clears the pickerWrapper and prepares it for being used again when idle
// mode is exited. // mode is exited.
func (pw *pickerWrapper) reset() { func (pw *pickerWrapper) reset() {
pw.mu.Lock() old := pw.pickerGen.Swap(&pickerGeneration{blockingCh: make(chan struct{})})
defer pw.mu.Unlock() close(old.blockingCh)
if pw.done {
return
}
pw.blockingCh = make(chan struct{})
} }
// 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

View File

@ -171,7 +171,7 @@ func (ccr *ccResolverWrapper) NewAddress(addrs []resolver.Address) {
// ParseServiceConfig is called by resolver implementations to parse a JSON // ParseServiceConfig is called by resolver implementations to parse a JSON
// representation of the service config. // 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, ccr.cc.dopts.maxCallAttempts)
} }
// addChannelzTraceEvent adds a channelz trace event containing the new // addChannelzTraceEvent adds a channelz trace event containing the new

View File

@ -26,6 +26,7 @@ import (
"time" "time"
"google.golang.org/grpc/balancer" "google.golang.org/grpc/balancer"
"google.golang.org/grpc/balancer/pickfirst"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/internal" "google.golang.org/grpc/internal"
"google.golang.org/grpc/internal/balancer/gracefulswitch" "google.golang.org/grpc/internal/balancer/gracefulswitch"
@ -163,9 +164,11 @@ type jsonSC struct {
} }
func init() { func init() {
internal.ParseServiceConfig = parseServiceConfig internal.ParseServiceConfig = func(js string) *serviceconfig.ParseResult {
return parseServiceConfig(js, defaultMaxCallAttempts)
}
} }
func parseServiceConfig(js string) *serviceconfig.ParseResult { func parseServiceConfig(js string, maxAttempts int) *serviceconfig.ParseResult {
if len(js) == 0 { if len(js) == 0 {
return &serviceconfig.ParseResult{Err: fmt.Errorf("no JSON service config provided")} return &serviceconfig.ParseResult{Err: fmt.Errorf("no JSON service config provided")}
} }
@ -183,12 +186,12 @@ func parseServiceConfig(js string) *serviceconfig.ParseResult {
} }
c := rsc.LoadBalancingConfig c := rsc.LoadBalancingConfig
if c == nil { if c == nil {
name := PickFirstBalancerName name := pickfirst.Name
if rsc.LoadBalancingPolicy != nil { if rsc.LoadBalancingPolicy != nil {
name = *rsc.LoadBalancingPolicy name = *rsc.LoadBalancingPolicy
} }
if balancer.Get(name) == nil { if balancer.Get(name) == nil {
name = PickFirstBalancerName name = pickfirst.Name
} }
cfg := []map[string]any{{name: struct{}{}}} cfg := []map[string]any{{name: struct{}{}}}
strCfg, err := json.Marshal(cfg) strCfg, err := json.Marshal(cfg)
@ -218,7 +221,7 @@ func parseServiceConfig(js string) *serviceconfig.ParseResult {
WaitForReady: m.WaitForReady, WaitForReady: m.WaitForReady,
Timeout: (*time.Duration)(m.Timeout), Timeout: (*time.Duration)(m.Timeout),
} }
if mc.RetryPolicy, err = convertRetryPolicy(m.RetryPolicy); err != nil { if mc.RetryPolicy, err = convertRetryPolicy(m.RetryPolicy, maxAttempts); err != nil {
logger.Warningf("grpc: unmarshalling service config %s: %v", js, err) logger.Warningf("grpc: unmarshalling service config %s: %v", js, err)
return &serviceconfig.ParseResult{Err: err} return &serviceconfig.ParseResult{Err: err}
} }
@ -264,7 +267,7 @@ func parseServiceConfig(js string) *serviceconfig.ParseResult {
return &serviceconfig.ParseResult{Config: &sc} return &serviceconfig.ParseResult{Config: &sc}
} }
func convertRetryPolicy(jrp *jsonRetryPolicy) (p *internalserviceconfig.RetryPolicy, err error) { func convertRetryPolicy(jrp *jsonRetryPolicy, maxAttempts int) (p *internalserviceconfig.RetryPolicy, err error) {
if jrp == nil { if jrp == nil {
return nil, nil return nil, nil
} }
@ -278,17 +281,16 @@ func convertRetryPolicy(jrp *jsonRetryPolicy) (p *internalserviceconfig.RetryPol
return nil, nil return nil, nil
} }
if jrp.MaxAttempts < maxAttempts {
maxAttempts = jrp.MaxAttempts
}
rp := &internalserviceconfig.RetryPolicy{ rp := &internalserviceconfig.RetryPolicy{
MaxAttempts: jrp.MaxAttempts, MaxAttempts: maxAttempts,
InitialBackoff: time.Duration(jrp.InitialBackoff), InitialBackoff: time.Duration(jrp.InitialBackoff),
MaxBackoff: time.Duration(jrp.MaxBackoff), MaxBackoff: time.Duration(jrp.MaxBackoff),
BackoffMultiplier: jrp.BackoffMultiplier, BackoffMultiplier: jrp.BackoffMultiplier,
RetryableStatusCodes: make(map[codes.Code]bool), RetryableStatusCodes: make(map[codes.Code]bool),
} }
if rp.MaxAttempts > 5 {
// TODO(retry): Make the max maxAttempts configurable.
rp.MaxAttempts = 5
}
for _, code := range jrp.RetryableStatusCodes { for _, code := range jrp.RetryableStatusCodes {
rp.RetryableStatusCodes[code] = true rp.RetryableStatusCodes[code] = true
} }

View File

@ -23,6 +23,7 @@ import (
"errors" "errors"
"io" "io"
"math" "math"
"math/rand"
"strconv" "strconv"
"sync" "sync"
"time" "time"
@ -34,7 +35,6 @@ import (
"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"
"google.golang.org/grpc/internal/grpcrand"
"google.golang.org/grpc/internal/grpcutil" "google.golang.org/grpc/internal/grpcutil"
imetadata "google.golang.org/grpc/internal/metadata" imetadata "google.golang.org/grpc/internal/metadata"
iresolver "google.golang.org/grpc/internal/resolver" iresolver "google.golang.org/grpc/internal/resolver"
@ -699,7 +699,7 @@ func (a *csAttempt) shouldRetry(err error) (bool, error) {
if max := float64(rp.MaxBackoff); cur > max { if max := float64(rp.MaxBackoff); cur > max {
cur = max cur = max
} }
dur = time.Duration(grpcrand.Int63n(int64(cur))) dur = time.Duration(rand.Int63n(int64(cur)))
cs.numRetriesSincePushback++ cs.numRetriesSincePushback++
} }

View File

@ -19,4 +19,4 @@
package grpc package grpc
// Version is the current grpc version. // Version is the current grpc version.
const Version = "1.64.0" const Version = "1.65.0"

22
vendor/modules.txt vendored
View File

@ -18,7 +18,7 @@ github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1
github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1 github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1
github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1 github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1
github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1 github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1
# github.com/cespare/xxhash/v2 v2.2.0 # github.com/cespare/xxhash/v2 v2.3.0
## explicit; go 1.11 ## explicit; go 1.11
github.com/cespare/xxhash/v2 github.com/cespare/xxhash/v2
# github.com/davecgh/go-spew v1.1.1 # github.com/davecgh/go-spew v1.1.1
@ -186,12 +186,12 @@ go.uber.org/zap/internal/exit
go.uber.org/zap/internal/pool go.uber.org/zap/internal/pool
go.uber.org/zap/internal/stacktrace go.uber.org/zap/internal/stacktrace
go.uber.org/zap/zapcore go.uber.org/zap/zapcore
# golang.org/x/mod v0.18.0 # golang.org/x/mod v0.19.0
## explicit; go 1.18 ## explicit; go 1.18
golang.org/x/mod/internal/lazyregexp golang.org/x/mod/internal/lazyregexp
golang.org/x/mod/module golang.org/x/mod/module
golang.org/x/mod/semver golang.org/x/mod/semver
# golang.org/x/net v0.26.0 # golang.org/x/net v0.27.0
## explicit; go 1.18 ## explicit; go 1.18
golang.org/x/net/http/httpguts golang.org/x/net/http/httpguts
golang.org/x/net/http2 golang.org/x/net/http2
@ -208,12 +208,12 @@ golang.org/x/oauth2/internal
## explicit; go 1.18 ## explicit; go 1.18
golang.org/x/sync/errgroup golang.org/x/sync/errgroup
golang.org/x/sync/semaphore golang.org/x/sync/semaphore
# golang.org/x/sys v0.21.0 # golang.org/x/sys v0.22.0
## explicit; go 1.18 ## explicit; go 1.18
golang.org/x/sys/plan9 golang.org/x/sys/plan9
golang.org/x/sys/unix golang.org/x/sys/unix
golang.org/x/sys/windows golang.org/x/sys/windows
# golang.org/x/term v0.21.0 # golang.org/x/term v0.22.0
## explicit; go 1.18 ## explicit; go 1.18
golang.org/x/term golang.org/x/term
# golang.org/x/text v0.16.0 # golang.org/x/text v0.16.0
@ -225,7 +225,7 @@ golang.org/x/text/unicode/norm
# golang.org/x/time v0.5.0 # golang.org/x/time v0.5.0
## explicit; go 1.18 ## explicit; go 1.18
golang.org/x/time/rate golang.org/x/time/rate
# golang.org/x/tools v0.22.0 # golang.org/x/tools v0.23.0
## explicit; go 1.19 ## explicit; go 1.19
golang.org/x/tools/go/ast/astutil golang.org/x/tools/go/ast/astutil
golang.org/x/tools/imports golang.org/x/tools/imports
@ -249,14 +249,15 @@ google.golang.org/genproto/googleapis/api/httpbody
# google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 # google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157
## explicit; go 1.20 ## explicit; go 1.20
google.golang.org/genproto/googleapis/rpc/status google.golang.org/genproto/googleapis/rpc/status
# google.golang.org/grpc v1.64.0 # google.golang.org/grpc v1.65.0
## explicit; go 1.19 ## explicit; go 1.21
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
google.golang.org/grpc/balancer google.golang.org/grpc/balancer
google.golang.org/grpc/balancer/base google.golang.org/grpc/balancer/base
google.golang.org/grpc/balancer/grpclb/state google.golang.org/grpc/balancer/grpclb/state
google.golang.org/grpc/balancer/pickfirst
google.golang.org/grpc/balancer/roundrobin google.golang.org/grpc/balancer/roundrobin
google.golang.org/grpc/binarylog/grpc_binarylog_v1 google.golang.org/grpc/binarylog/grpc_binarylog_v1
google.golang.org/grpc/channelz google.golang.org/grpc/channelz
@ -278,7 +279,6 @@ google.golang.org/grpc/internal/channelz
google.golang.org/grpc/internal/credentials google.golang.org/grpc/internal/credentials
google.golang.org/grpc/internal/envconfig google.golang.org/grpc/internal/envconfig
google.golang.org/grpc/internal/grpclog google.golang.org/grpc/internal/grpclog
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/idle
@ -684,10 +684,10 @@ k8s.io/utils/pointer
k8s.io/utils/ptr k8s.io/utils/ptr
k8s.io/utils/strings/slices k8s.io/utils/strings/slices
k8s.io/utils/trace k8s.io/utils/trace
# knative.dev/hack v0.0.0-20240607132042-09143140a254 # knative.dev/hack v0.0.0-20240704013904-b9799599afcf
## explicit; go 1.18 ## explicit; go 1.18
knative.dev/hack knative.dev/hack
# knative.dev/pkg v0.0.0-20240626134149-3f6a546ac3a4 # knative.dev/pkg v0.0.0-20240708181110-b4e5f07a2c37
## explicit; go 1.22 ## explicit; go 1.22
knative.dev/pkg/apis knative.dev/pkg/apis
knative.dev/pkg/apis/duck knative.dev/pkg/apis/duck