Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aggregate Universe Stats: always store result of querySyncStats #1302

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 43 additions & 6 deletions tapdb/universe_stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -575,14 +575,48 @@ func (u *UniverseStats) AggregateSyncStats(

log.Debugf("Populating aggregate sync stats")

dbStats, err := u.querySyncStats(ctx)
if err != nil {
var (
resChan = make(chan universe.AggregateStats, 1)
errChan = make(chan error, 1)
dbStats universe.AggregateStats
)

// We'll fire the db query in a separate go routine, with an undefined
// timeout. This way, we'll always retrieve the result regardless of
// what happens in the current context. This way we're always waiting
// for the call to complete and caching the result even if this
// function's result is an error.
go func() {
// Note: we have the statsMtx held, so even if a burst of
// requests took place in an un-cached state, this call would
// not be triggered multiple times.
dbStats, err := u.querySyncStats(context.Background())
if err != nil {
errChan <- err
return
}

log.Debugf("Retrieved aggregate sync stats: %+v", dbStats)

// We'll store the DB stats so that it can be read from cache
// later.
u.statsSnapshot.Store(&dbStats)

resChan <- dbStats
}()

select {
case <-ctx.Done():
log.Debugf("ctx timeout before retrieving aggregate sync stats")
return dbStats, ctx.Err()

case err := <-errChan:
log.Debugf("error while querying aggregate sync stats: %v", err)
return dbStats, err
}

// We'll store the DB stats then start our time after function to wipe
// the stats pointer so we'll refresh it after a period of time.
u.statsSnapshot.Store(&dbStats)
case res := <-resChan:
dbStats = res
}

// Reset the timer so we'll refresh again after the cache duration.
if u.statsRefresh != nil && !u.statsRefresh.Stop() {
Expand All @@ -591,6 +625,9 @@ func (u *UniverseStats) AggregateSyncStats(
default:
}
}

log.Debugf("Refreshing sync stats cache in %v", u.opts.cacheDuration)

u.statsRefresh = time.AfterFunc(
u.opts.cacheDuration, u.populateSyncStatsCache,
)
Expand Down
Loading