aboutsummaryrefslogtreecommitdiff
path: root/devtools/cmd
diff options
context:
space:
mode:
authorJonathan Amsterdam <jba@google.com>2021-08-06 05:48:38 -0400
committerJonathan Amsterdam <jba@google.com>2021-08-06 13:31:04 +0000
commite5369648ac25aa7ffed27fa1fc91c5f157e7cb42 (patch)
tree0a44b7529d229d18be35f0dddafed8e061dce1ef /devtools/cmd
parent720e7fc50eedba24b36b8da9ebfd817e067dc8ba (diff)
downloadgo-x-pkgsite-e5369648ac25aa7ffed27fa1fc91c5f157e7cb42.tar.xz
devtools/cmd/seeddb: process same module sequentially
Process multiple versions of the same module sequentially. Doing so in parallel causes DB contention because of the lock on the module path and other ordinary DB locks. This can cause a fetch to reach the limit on the number of transaction retries. Change-Id: Ibb58e583441e0b471a628edd1b64ec7f8010e174 Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/340118 Trust: Jonathan Amsterdam <jba@google.com> Run-TryBot: Jonathan Amsterdam <jba@google.com> Reviewed-by: Julie Qiu <julie@golang.org>
Diffstat (limited to 'devtools/cmd')
-rw-r--r--devtools/cmd/seeddb/main.go91
1 files changed, 52 insertions, 39 deletions
diff --git a/devtools/cmd/seeddb/main.go b/devtools/cmd/seeddb/main.go
index 4e83f582..ed18c296 100644
--- a/devtools/cmd/seeddb/main.go
+++ b/devtools/cmd/seeddb/main.go
@@ -87,48 +87,19 @@ func run(ctx context.Context, db *database.DB, proxyURL string) error {
}
for _, m := range seedModules {
m := m
- vers := []string{m.Version}
- if m.Version == "all" {
- if m.Path == stdlib.ModulePath {
- stdVersions, err := stdlib.Versions()
- if err != nil {
- return err
- }
- // As an optimization, only fetch release versions for the
- // standard library.
- vers = nil
- for _, v := range stdVersions {
- if strings.HasSuffix(v, ".0") {
- vers = append(vers, v)
- }
- }
- } else {
- vers, err = proxyClient.Versions(ctx, m.Path)
- if err != nil {
- return err
- }
- }
+ vers, err := versions(ctx, proxyClient, m)
+ if err != nil {
+ return err
}
- for _, v := range vers {
- v := v
- g.Go(func() error {
- // Record the duration of this fetch request.
- start := time.Now()
-
- var exists bool
- defer func() {
- r.add(m.Path, v, start, exists)
- }()
- err := db.QueryRow(ctx, `SELECT 1 FROM modules WHERE module_path = $1 AND version = $2;`, m.Path, v).Scan(&exists)
- if err != nil && !errors.Is(err, sql.ErrNoRows) {
+ // Process versions of the same module sequentially, to avoid DB contention.
+ g.Go(func() error {
+ for _, v := range vers {
+ if err := fetch(ctx, db, f, m.Path, v, &r); err != nil {
return err
}
- if errors.Is(err, sql.ErrNoRows) || *refetch {
- return fetchFunc(ctx, f, m.Path, v)
- }
- return nil
- })
- }
+ }
+ return nil
+ })
}
if err := g.Wait(); err != nil {
return err
@@ -147,6 +118,48 @@ func run(ctx context.Context, db *database.DB, proxyURL string) error {
return nil
}
+func versions(ctx context.Context, proxyClient *proxy.Client, mv internal.Modver) ([]string, error) {
+ if mv.Version != "all" {
+ return []string{mv.Version}, nil
+ }
+ if mv.Path == stdlib.ModulePath {
+ stdVersions, err := stdlib.Versions()
+ if err != nil {
+ return nil, err
+ }
+ // As an optimization, only fetch release versions for the standard
+ // library.
+ var vers []string
+ for _, v := range stdVersions {
+ if strings.HasSuffix(v, ".0") {
+ vers = append(vers, v)
+ }
+ }
+ return vers, nil
+ }
+ return proxyClient.Versions(ctx, mv.Path)
+}
+
+func fetch(ctx context.Context, db *database.DB, f *worker.Fetcher, m, v string, r *results) error {
+ // Record the duration of this fetch request.
+ start := time.Now()
+
+ var exists bool
+ defer func() {
+ r.add(m, v, start, exists)
+ }()
+ err := db.QueryRow(ctx, `
+ SELECT 1 FROM modules WHERE module_path = $1 AND version = $2;
+ `, m, v).Scan(&exists)
+ if err != nil && !errors.Is(err, sql.ErrNoRows) {
+ return err
+ }
+ if errors.Is(err, sql.ErrNoRows) || *refetch {
+ return fetchFunc(ctx, f, m, v)
+ }
+ return nil
+}
+
func fetchFunc(ctx context.Context, f *worker.Fetcher, m, v string) (err error) {
defer derrors.Wrap(&err, "fetchFunc(ctx, f, %q, %q)", m, v)