你正在使用的Go版本是什么( go version
)?
$ go version
go version go1.20.2 linux/amd64
这个问题在最新版本中是否重现?
是的
你正在使用什么操作系统和处理器架构( go env
)?
go env
输出
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/net_home/alatter/.cache/go-build"
GOENV="/net_home/alatter/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/net_home/alatter/go/pkg/mod"
GONOPROXY="*."
GONOSUMDB="*."
GOOS="linux"
GOPATH="/net_home/alatter/go"
GOPRIVATE="*.epic.com"
GOPROXY=",direct"
GOROOT="/net_home/alatter/local/go1.20.2.linux-amd64"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/net_home/alatter/local/go1.20.2.linux-amd64/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.20.2"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/net_home/alatter/source/pkgsite/go.mod"
GOWORK=""
CGO_CFLAGS="-O2 -g"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-O2 -g"
CGO_FFLAGS="-O2 -g"
CGO_LDFLAGS="-O2 -g"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build1051915940=/tmp/go-build -gno-record-gcc-switches"
你做了什么?
我们运行pkgsite并将其内部托管,以便为我们自己的包提供文档。我们在“直接”模式下运行它,并通过我们的内部go-proxy(Athena)发送,该代理具有获取我们内部go-modules的凭据。
我们使用以下参数运行pkgsite:
$ go run ./cmd/frontend -bypass_license_check -direct_proxy -proxy_url https://<redacted> -host :8080
在提交f159e616582641bdbeb2d6a0018ca4c8c472fbb5之后,我们无法再加载godocs
对于stdlib包 - 例如,加载http://localhost:8080/io
将返回HTTP-500,其中包含来自pkgsite的以下日志:
2023/09/26 15:11:41 Info: Listening on addr :8080
2023/09/26 15:11:46 Info: 0 /io map[requestType:request start]
2023/09/26 15:11:46 Info: FetchDataSource: fetching std@latest
2023/09/26 15:11:46 Info: FetchDataSource: fetched std@latest using *fetch.proxyModuleGetter in 226.3µs with error FetchModule("std", "latest"): proxy.Client.Info("std", "latest"): Client.readBody("std", "latest", "info"): Client.escapedURL("std", "latest", "info"): path: malformed module path "std": missing dot in first path element: invalid argument
2023/09/26 15:11:46 Error: serveUnitPage(ctx, w, r, ds, &{io std latest}): FetchDataSource.GetUnitMeta("io", "std", "latest"): FetchDataSource.findModule("io", "std", "latest"): FetchDataSource.getModule("std", "latest"): FetchModule("std", "latest"): proxy.Client.Info("std", "latest"): Client.readBody("std", "latest", "info"): Client.escapedURL("std", "latest", "info"): path: malformed module path "std": missing dot in first path element: invalid argument
2023/09/26 15:11:46 Info: 500 /io map[isRobot:false requestType:request end]
错误malformed module path "std": missing dot in first path element: invalid argument
似乎来自我们的go-proxy(Athena)。它被拒绝一个名为std的模块,这似乎是合理的拒绝。
(编辑:进一步测试后发现错误是pkgsite内部的 - 直接代理模式下的加载stdlib模块似乎与该模式不兼容)
如果我在前端启动的direct-mode分支的fetchdatasource.Options中交换使用的getter顺序,对我来说一切都可以正常工作:
if *directProxy {
sourceClient := source.NewClient(&http.Client{Transport: &ochttp.Transport{}, Timeout: 1 * time.Minute})
ds := fetchdatasource.Options{
Getters: []fetch.ModuleGetter{
fetch.NewProxyModuleGetter(proxyClient, sourceClient), // <-- if I move this down one line my problem goes away
fetch.NewStdlibZipModuleGetter(),
},
ProxyClientForLatest: proxyClient,
BypassLicenseCheck: *bypassLicenseCheck,
}.New()
dsg = func(context.Context) internal.DataSource { return ds }
} else {
二分查找结果:
f159e616582641bdbeb2d6a0018ca4c8c472fbb5 is the first bad commit
commit f159e616582641bdbeb2d6a0018ca4c8c472fbb5
Author: Michael Matloob <matloob@golang.org>
Date: Wed Jul 5 14:02:46 2023 -0400
internal/fetch: add two stdlib getters
This breaks out the behavior of getting the stdlib into its own
getter, stdlibZipModuleGetter. Most (but not all) of the special cases
in the fetch code for the stdlib are in the stdlibZipModuleGetter,
which is installed on the frontend. For the local pkgsite command, we
add a new builder for the goPackagesModuleGetter that loads the
packages from the stdlib given a GOROOT. The stdlibZipModuleGetter is
also installed for pkgsite in as a fallback if the
goPackagesModuleGetter doesn't successfully fetch the stdlib module
(I'm not sure if that's possible).
Fixes #60114
Change-Id: Ida6a5367343643cc337c6d05e0d40095f79ca9e5
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/507883
Reviewed-by: Jamal Carvalho <jamal@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Michael Matloob <matloob@golang.org>
kokoro-CI: kokoro <noreply+kokoro@google.com>
9条答案
按热度按时间b5buobof1#
如果我在前端启动的直接模式分支中交换fetchdatasource.Options中使用的getters的顺序,似乎对我来说一切都正常:
嗯。我怀疑这是
fetch.proxyModuleGetter
的一个bug。./internal/fetchdatasource
检查derrors.NotFound
以跳过错误:https://cs.opensource.google/go/x/pkgsite/+/master:internal/fetchdatasource/fetchdatasource.go;l=166-168;drc=14233af499055be3ba3fe6816af8e7d4a4efa9ad
可能如果从
fetch.proxyModuleGetter
请求一个具有无效路径的模块,它应该返回一个错误,其中errors.Is(err, derrors.NotFound)
返回true。@aslatter,想要发送修复吗?
snz8szmq2#
解:要使$\dfrac{x+3}{2}\le 10$,
$x+3\le 20$,
$x\le 17$.
故答案为$x\le 17$。
lp0sw83n3#
这似乎对于转换来说是一个太低的级别。
看起来在
./internal/fetch
中已经有了针对标准库的特殊情况:https://cs.opensource.google/go/x/pkgsite/+/master:internal/fetch/fetch.go;l=77-104;drc=14233af499055be3ba3fe6816af8e7d4a4efa9ad
也许
if fr.ModulePath == stdlib.ModulePath
条件应该在switch mg.(type)
之前移动?j5fpnvbx4#
我想到了两个选项:
这两种方法都感觉有点不太好 - (2)具有更高的组件耦合密度,但(1)需要代理客户端了解"std"模块。
我对问题描述中获取器的顺序进行的评论并不是一个严肃的建议 - 它更多地描述了我为了诊断问题而采取的行动。但它似乎并不比这些选项更糟?每个由stdlib-getter处理的模块都无法由proxy-getter处理。
z2acfund5#
CC @jba
zmeyuzjn6#
就我所知,这个问题是运行在"直接代理"模式下的障碍。任何解决方法都将不胜感激(或者对于非代理模式的运行提供指导/建议)。
我很乐意发送修复程序,但似乎我们想要采取的方向并不明确。
pbpqsu0x7#
我不确定这是否相关,但即使在数据库模式下,我也无法让前端提供stdlib(只能得到404响应)。据我所知,数据库必须填充stdlib信息,但这只由一个工作器完成,而这个工作器只有在前端托管在GCP上时才会运行?我很难理解这一切是如何运作的。
wz1wpwve8#
我预计这是一个不同的问题——在直接代理模式下,如果请求被路由到后端进行处理,那么stdlib浏览几乎可以正常工作。一旦发生这种情况,发现/下载就会在实时进行,类似于代理发现的包/模块。
eivnm1vs9#
是的,我想我弄明白了需要运行
seeddb
来用标准库信息填充数据库。不幸的是,当我运行它时,我的PostgreSQL示例由于OOM错误(32GB的RAM)而被终止。所以这与直接代理模式无关,但我不知道为什么前端在使用数据库运行时不直接获取标准库,就像获取任何其他缺失的包一样。