Skip to content

Commit 63629dc

Browse files
committed
internal/postgres,worker: schedule fetching of std@master
In order to ensure that pkg.go.dev/std@master is always showing the latest version, an endpoint is added which checks for the most recent version of std@master. If the version in our database is not up to date, a fetch request is scheduled. Additionally, since only the most recent pseudoversion of std is ever shown on pkg.go.dev, older versions are deleted. For golang/go#44390 Change-Id: Iad56b8653f378fb5a7d72a1e30505da090de279d Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/294350 Trust: Julie Qiu <[email protected]> Run-TryBot: Julie Qiu <[email protected]> TryBot-Result: kokoro <[email protected]> Reviewed-by: Jonathan Amsterdam <[email protected]>
1 parent 28ffb9f commit 63629dc

File tree

3 files changed

+114
-0
lines changed

3 files changed

+114
-0
lines changed

internal/postgres/delete.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright 2019 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package postgres
6+
7+
import (
8+
"context"
9+
"database/sql"
10+
11+
"github.com/lib/pq"
12+
"golang.org/x/pkgsite/internal/database"
13+
"golang.org/x/pkgsite/internal/derrors"
14+
)
15+
16+
// DeletePseudoversionsExcept deletes all pseudoversions for the module except
17+
// the provided resolvedVersion.
18+
func (db *DB) DeletePseudoversionsExcept(ctx context.Context, modulePath, resolvedVersion string) (err error) {
19+
defer derrors.WrapStack(&err, "DeletePseudoversionsExcept(ctx, db, %q, %q)", modulePath, resolvedVersion)
20+
return db.db.Transact(ctx, sql.LevelDefault, func(tx *database.DB) error {
21+
var versions []string
22+
collect := func(rows *sql.Rows) error {
23+
var version string
24+
if err := rows.Scan(&version); err != nil {
25+
return err
26+
}
27+
versions = append(versions, version)
28+
return nil
29+
}
30+
const stmt = `
31+
DELETE FROM modules
32+
WHERE version_type = 'pseudo' AND module_path=$1 AND version != $2
33+
RETURNING version`
34+
if err := tx.RunQuery(ctx, stmt, collect, modulePath, resolvedVersion); err != nil {
35+
return err
36+
}
37+
_, err := tx.Exec(ctx, `DELETE FROM version_map WHERE module_path = $1 AND resolved_version = ANY($2)`,
38+
modulePath, pq.Array(versions))
39+
return err
40+
})
41+
}

internal/postgres/delete_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright 2019 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package postgres
6+
7+
import (
8+
"context"
9+
"testing"
10+
11+
"golang.org/x/pkgsite/internal/testing/sample"
12+
"golang.org/x/pkgsite/internal/version"
13+
)
14+
15+
func TestDeletePseudoversionsExcept(t *testing.T) {
16+
t.Parallel()
17+
ctx := context.Background()
18+
testDB, release := acquire(t)
19+
defer release()
20+
21+
pseudo1 := "v0.0.0-20190904010203-89fb59e2e920"
22+
versions := []string{
23+
sample.VersionString,
24+
pseudo1,
25+
"v0.0.0-20190904010203-89fb59e2e920",
26+
"v0.0.0-20190904010203-89fb59e2e920",
27+
}
28+
for _, v := range versions {
29+
MustInsertModule(ctx, t, testDB, sample.Module(sample.ModulePath, v, ""))
30+
}
31+
if err := testDB.DeletePseudoversionsExcept(ctx, sample.ModulePath, pseudo1); err != nil {
32+
t.Fatal(err)
33+
}
34+
mods, err := getPathVersions(ctx, testDB, sample.ModulePath, version.TypeRelease)
35+
if err != nil {
36+
t.Fatal(err)
37+
}
38+
if len(mods) != 1 && mods[0].Version != sample.VersionString {
39+
t.Errorf("module version %q was not found", sample.VersionString)
40+
}
41+
mods, err = getPathVersions(ctx, testDB, sample.ModulePath, version.TypePseudo)
42+
if err != nil {
43+
t.Fatal(err)
44+
}
45+
if len(mods) != 1 {
46+
t.Fatalf("pseudoversions expected to be deleted were not")
47+
}
48+
if mods[0].Version != pseudo1 {
49+
t.Errorf("got %q; want %q", mods[0].Version, pseudo1)
50+
}
51+
}

internal/worker/server.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,11 @@ func (s *Server) Install(handle func(string, http.Handler)) {
152152
// Google Cloud Task Queues.
153153
handle("/fetch/", http.StripPrefix("/fetch", rmw(http.HandlerFunc(s.handleFetch))))
154154

155+
// scheduled: fetch-std-master checks if the std@master version in the
156+
// database is up to date with the version at HEAD. If not, a fetch request
157+
// is queued to refresh the std@master version.
158+
handle("/fetch-std-master/", rmw(s.errorHandler(s.handleFetchStdMaster)))
159+
155160
// scheduled: enqueue queries the module_version_states table for the next
156161
// batch of module versions to process, and enqueues them for processing.
157162
// Normally this will not cause duplicate processing, because Cloud Tasks
@@ -453,6 +458,23 @@ func (s *Server) handleHTMLPage(f func(w http.ResponseWriter, r *http.Request) e
453458
}
454459
}
455460

461+
func (s *Server) handleFetchStdMaster(w http.ResponseWriter, r *http.Request) error {
462+
_, resolvedVersion, _, err := stdlib.Zip("master")
463+
if err != nil {
464+
return err
465+
}
466+
vm, err := s.db.GetVersionMap(r.Context(), stdlib.ModulePath, "master")
467+
if err != nil {
468+
return err
469+
}
470+
if vm.ResolvedVersion != resolvedVersion {
471+
if _, err := s.queue.ScheduleFetch(r.Context(), stdlib.ModulePath, "master", "", false); err != nil {
472+
return fmt.Errorf("error scheduling fetch for %s: %w", "master", err)
473+
}
474+
}
475+
return s.db.DeletePseudoversionsExcept(r.Context(), stdlib.ModulePath, vm.ResolvedVersion)
476+
}
477+
456478
func (s *Server) handlePopulateStdLib(w http.ResponseWriter, r *http.Request) error {
457479
msg, err := s.doPopulateStdLib(r.Context(), r.FormValue("suffix"))
458480
w.Header().Set("Content-Type", "text/plain; charset=utf-8")

0 commit comments

Comments
 (0)