Serve deb virtual indexes by hash and bound cached suites
This commit is contained in:
@@ -51,11 +51,14 @@ func (r *DebRepo) files() map[string][]byte { return r.Files }
|
||||
// holding the previous index can still fetch the files it references.
|
||||
type repoGen struct {
|
||||
cur, prev mergedRepo
|
||||
at time.Time
|
||||
at, used time.Time
|
||||
}
|
||||
|
||||
const rpmMergeTTL = 60 * time.Second
|
||||
|
||||
// maxDebSuites bounds the client-chosen suites cached per deb virtual.
|
||||
const maxDebSuites = 32
|
||||
|
||||
func NewEngine(db *database.DB, proxyEngine *proxy.Engine) *Engine {
|
||||
e := &Engine{db: db, proxyEngine: proxyEngine, getRemote: db.GetRemote, mergeTTL: rpmMergeTTL}
|
||||
e.rpmMember = e.fetchRPMMember
|
||||
@@ -276,6 +279,7 @@ func (e *Engine) merged(ctx context.Context, key string, merge func(context.Cont
|
||||
e.mu.Lock()
|
||||
g := e.gens[key]
|
||||
if g != nil && time.Since(g.at) < e.mergeTTL {
|
||||
g.used = time.Now()
|
||||
e.mu.Unlock()
|
||||
return g.cur, nil
|
||||
}
|
||||
@@ -294,12 +298,12 @@ func (e *Engine) merged(ctx context.Context, key string, merge func(context.Cont
|
||||
g := e.gens[key]
|
||||
switch {
|
||||
case g == nil:
|
||||
e.gens[key] = &repoGen{cur: repo, at: time.Now()}
|
||||
e.gens[key] = &repoGen{cur: repo, at: time.Now(), used: time.Now()}
|
||||
case string(g.cur.index()) == string(repo.index()):
|
||||
g.at = time.Now()
|
||||
g.at, g.used = time.Now(), time.Now()
|
||||
repo = g.cur
|
||||
default:
|
||||
g.prev, g.cur, g.at = g.cur, repo, time.Now()
|
||||
g.prev, g.cur, g.at, g.used = g.cur, repo, time.Now(), time.Now()
|
||||
}
|
||||
return repo, nil
|
||||
})
|
||||
@@ -368,6 +372,7 @@ func (e *Engine) fetchDeb(ctx context.Context, virt models.Virtual, reqPath stri
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
e.evictLRU("deb\x00"+virt.Name+"\x00", maxDebSuites)
|
||||
if name == "Release" {
|
||||
return repo.index(), "text/plain", nil
|
||||
}
|
||||
@@ -408,6 +413,22 @@ func (e *Engine) fetchDebMember(ctx context.Context, name, base string) (*DebMem
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// evictLRU drops the least recently used merges under prefix beyond keep.
|
||||
func (e *Engine) evictLRU(prefix string, keep int) {
|
||||
e.mu.Lock()
|
||||
defer e.mu.Unlock()
|
||||
var keys []string
|
||||
for k := range e.gens {
|
||||
if strings.HasPrefix(k, prefix) {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
}
|
||||
slices.SortFunc(keys, func(a, b string) int { return e.gens[b].used.Compare(e.gens[a].used) })
|
||||
for _, k := range keys[min(len(keys), keep):] {
|
||||
delete(e.gens, k)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Engine) cachedFile(key, path string) ([]byte, bool) {
|
||||
e.mu.Lock()
|
||||
defer e.mu.Unlock()
|
||||
@@ -420,6 +441,7 @@ func (e *Engine) cachedFile(key, path string) ([]byte, bool) {
|
||||
continue
|
||||
}
|
||||
if body, ok := r.files()[path]; ok {
|
||||
g.used = time.Now()
|
||||
return body, true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user