Skip to content
quarry Artifact [b26f4d9461]
Login

Artifact [b26f4d9461]

Artifact b26f4d9461862060b78cd6983ef87a6876fa2c0eb857dfac563128e16b1d13e0:


package web

import (
	"net/url"
	"sync"
	"time"

	"golang.org/x/sync/singleflight"
)

// The home page's content is the expensive part of the page: it reaches
// into every tracker the reader can see, which is a few hundred
// milliseconds warm and seconds when those indexes are cold. The page
// must arrive at once and never blank, so the content is remembered per
// reader and view, drawn from memory on the next visit, and brought up
// to date in place; and a page with nothing remembered gives the content
// dashBudget to arrive with it before streaming it in.

// dashBudget is how long a page with nothing remembered waits for its
// content before arriving without it.
const dashBudget = 150 * time.Millisecond

// dashKeep is how long a remembered dashboard may be drawn. It is
// replaced at once by the fresh one; the bound is on what a reader can
// glimpse of a view that has since changed under them (a repository
// they no longer reach, say).
const dashKeep = 10 * time.Minute

// dashCacheMax bounds the remembered dashboards; past it the memory is
// cleared rather than grown.
const dashCacheMax = 4096

type dashEntry struct {
	html string
	at   time.Time
}

var (
	dashFlight singleflight.Group
	dashMu     sync.Mutex
	dashCache  = map[string]dashEntry{}
)

// dashKey names one reader's view: the account and the query, without
// the fragment marker that asked for it.
func dashKey(user string, q url.Values) string {
	v := url.Values{}
	for k, vs := range q {
		if k != "frag" {
			v[k] = vs
		}
	}
	return user + "\x00" + v.Encode()
}

func dashRemember(key, html string) {
	dashMu.Lock()
	defer dashMu.Unlock()
	if len(dashCache) >= dashCacheMax {
		clear(dashCache)
	}
	dashCache[key] = dashEntry{html: html, at: time.Now()}
}

func dashRecall(key string) (string, bool) {
	dashMu.Lock()
	defer dashMu.Unlock()
	e, ok := dashCache[key]
	if !ok || time.Since(e.at) > dashKeep {
		return "", false
	}
	return e.html, true
}