router: add singleflight deduplication for concurrent narinfo races
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: Ib682889f34ad4ad4fb331ee2924dc9916a6a6964
This commit is contained in:
parent
e567491856
commit
41b18dd1f8
8 changed files with 90 additions and 18 deletions
|
|
@ -11,6 +11,7 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sync/singleflight"
|
||||
"notashelf.dev/ncro/internal/cache"
|
||||
"notashelf.dev/ncro/internal/metrics"
|
||||
"notashelf.dev/ncro/internal/narinfo"
|
||||
|
|
@ -37,18 +38,21 @@ type Router struct {
|
|||
prober *prober.Prober
|
||||
routeTTL time.Duration
|
||||
raceTimeout time.Duration
|
||||
negativeTTL time.Duration
|
||||
client *http.Client
|
||||
mu sync.RWMutex
|
||||
upstreamKeys map[string]string // upstream URL → Nix public key string
|
||||
group singleflight.Group
|
||||
}
|
||||
|
||||
// Creates a Router.
|
||||
func New(db *cache.DB, p *prober.Prober, routeTTL, raceTimeout time.Duration) *Router {
|
||||
func New(db *cache.DB, p *prober.Prober, routeTTL, raceTimeout, negativeTTL time.Duration) *Router {
|
||||
return &Router{
|
||||
db: db,
|
||||
prober: p,
|
||||
routeTTL: routeTTL,
|
||||
raceTimeout: raceTimeout,
|
||||
negativeTTL: negativeTTL,
|
||||
client: &http.Client{Timeout: raceTimeout},
|
||||
upstreamKeys: make(map[string]string),
|
||||
}
|
||||
|
|
@ -82,7 +86,14 @@ func (r *Router) Resolve(storeHash string, candidates []string) (*Result, error)
|
|||
}
|
||||
}
|
||||
metrics.NarinfoCacheMisses.Inc()
|
||||
return r.race(storeHash, candidates)
|
||||
|
||||
v, raceErr, _ := r.group.Do(storeHash, func() (interface{}, error) {
|
||||
return r.race(storeHash, candidates)
|
||||
})
|
||||
if raceErr != nil {
|
||||
return nil, raceErr
|
||||
}
|
||||
return v.(*Result), nil
|
||||
}
|
||||
|
||||
type raceResult struct {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue