~sircmpwn/godocs.io

gddo-server: Invalidate Etag when subpackages & importers updated v1 APPLIED

Teddy Wing
Teddy Wing: 1
 gddo-server: Invalidate Etag when subpackages & importers updated

 1 files changed, 28 insertions(+), 9 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~sircmpwn/godocs.io/patches/23395/mbox | git am -3
Learn more about email & git
View this thread in the archives

[PATCH] gddo-server: Invalidate Etag when subpackages & importers updated Export this patch

Teddy Wing
Partially revert the Etag change in
be62deeb42eeb7a2a467b9751e34108d8e498047. That change removed
subpackages and importer count from the Etag hash. This meant that even
if subpackages changed, the old cached version would be loaded.

Packages with many subpackages (like `google.golang.org/api`) can take
time before they're fully fetched in the background. Once the package
was fetched with a partial list of subpackages, none of the rest of the
subpackages would appear on subsequent page reloads due to the Etag
cache, even though more subpackages had been saved into the database.

Restore some of the prior Etag behaviour, including the subpackages and
importer count in the hash. This invalidates the cache when subpackages
are added so they can be seen on a page refresh.

I'm unclear on what the `importerCount` limit at 8 is for, but figured
I'd reuse the code from just before
be62deeb42eeb7a2a467b9751e34108d8e498047.
---
Here's what it looks like before:

https://teddywing.com/files/patches/gddo/etag/Before.webm

and after:

https://teddywing.com/files/patches/gddo/etag/After.webm

 gddo-server/http.go | 37 ++++++++++++++++++++++++++++---------
 1 file changed, 28 insertions(+), 9 deletions(-)

diff --git a/gddo-server/http.go b/gddo-server/http.go
index e4960fe..3a1e167 100644
--- a/gddo-server/http.go
+++ b/gddo-server/http.go
@@ -12,6 +12,7 @@ import (
	"net/http"
	"path/filepath"
	"runtime/debug"
	"strconv"
	"strings"
	"time"

@@ -64,11 +65,29 @@ func (s *Server) HTTPHandler() (http.Handler, error) {
}

// httpEtag returns the package entity tag used in HTTP transactions.
func (s *Server) httpEtag(importPath, version string, flashMessages []flashMessage) string {
func (s *Server) httpEtag(
	pkg *database.Package,
	subpkgs []database.Package,
	importerCount int,
	flashMessages []flashMessage,
) string {
	b := make([]byte, 0, 128)
	b = append(b, importPath...)
	b = append(b, pkg.ImportPath...)
	b = append(b, 0)
	b = append(b, version...)
	b = append(b, pkg.Version...)

	if importerCount >= 8 {
		importerCount = 8
	}

	b = strconv.AppendInt(b, int64(importerCount), 16)
	for _, subpkg := range subpkgs {
		b = append(b, 0)
		b = append(b, subpkg.ImportPath...)
		b = append(b, 0)
		b = append(b, subpkg.Synopsis...)
	}

	for _, m := range flashMessages {
		b = append(b, 0)
		b = append(b, m.ID...)
@@ -192,12 +211,6 @@ func (s *Server) servePackage(resp http.ResponseWriter, req *http.Request) error
		return nil

	default:
		etag := s.httpEtag(pkg.ImportPath, pkg.Version, flashMessages)
		status := http.StatusOK
		if req.Header.Get("If-None-Match") == etag {
			status = http.StatusNotModified
		}

		importCount, err := s.db.ImportCount(req.Context(), importPath)
		if err != nil {
			return err
@@ -210,6 +223,12 @@ func (s *Server) servePackage(resp http.ResponseWriter, req *http.Request) error
		}
		tctx.Package.SubPackages = subpkgs

		etag := s.httpEtag(pkg, subpkgs, importCount, flashMessages)
		status := http.StatusOK
		if req.Header.Get("If-None-Match") == etag {
			status = http.StatusNotModified
		}

		resp.Header().Set("Etag", etag)
		return s.templates.ExecuteHTML(resp, "doc.html", status, &tctx)
	}
-- 
2.27.0
Thanks!

To git@git.sr.ht:~sircmpwn/gddo
   df74f2d..5909268  master -> master