|
|
|
@ -19,6 +19,7 @@ import ( |
|
|
|
|
"github.com/grafana/loki/pkg/storage/stores/shipper/storage" |
|
|
|
|
"github.com/grafana/loki/pkg/tenant" |
|
|
|
|
util_log "github.com/grafana/loki/pkg/util/log" |
|
|
|
|
"github.com/grafana/loki/pkg/util/spanlogger" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
// timeout for downloading initial files for a table to avoid leaking resources by allowing it to take all the time.
|
|
|
|
@ -158,7 +159,7 @@ func (t *table) MultiQueries(ctx context.Context, queries []chunk.IndexQuery, ca |
|
|
|
|
|
|
|
|
|
// query both user and common index
|
|
|
|
|
for _, uid := range []string{userID, ""} { |
|
|
|
|
indexSet, err := t.getOrCreateIndexSet(uid, true) |
|
|
|
|
indexSet, err := t.getOrCreateIndexSet(ctx, uid, true) |
|
|
|
|
if err != nil { |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
@ -258,7 +259,7 @@ func (t *table) Sync(ctx context.Context) error { |
|
|
|
|
// Caller can use IndexSet.AwaitReady() to wait until the IndexSet gets ready, if required.
|
|
|
|
|
// forQuerying must be set to true only getting the index for querying since
|
|
|
|
|
// it captures the amount of time it takes to download the index at query time.
|
|
|
|
|
func (t *table) getOrCreateIndexSet(id string, forQuerying bool) (IndexSet, error) { |
|
|
|
|
func (t *table) getOrCreateIndexSet(ctx context.Context, id string, forQuerying bool) (IndexSet, error) { |
|
|
|
|
t.indexSetsMtx.RLock() |
|
|
|
|
indexSet, ok := t.indexSets[id] |
|
|
|
|
t.indexSetsMtx.RUnlock() |
|
|
|
@ -293,9 +294,11 @@ func (t *table) getOrCreateIndexSet(id string, forQuerying bool) (IndexSet, erro |
|
|
|
|
if forQuerying { |
|
|
|
|
start := time.Now() |
|
|
|
|
defer func() { |
|
|
|
|
duration := time.Since(start).Seconds() |
|
|
|
|
t.metrics.queryTimeTableDownloadDurationSeconds.WithLabelValues(t.name).Add(duration) |
|
|
|
|
level.Info(loggerWithUserID(t.logger, id)).Log("msg", "downloaded index set at query time", "duration", duration) |
|
|
|
|
duration := time.Since(start) |
|
|
|
|
t.metrics.queryTimeTableDownloadDurationSeconds.WithLabelValues(t.name).Add(duration.Seconds()) |
|
|
|
|
|
|
|
|
|
logger := spanlogger.FromContextWithFallback(ctx, loggerWithUserID(t.logger, id)) |
|
|
|
|
level.Info(logger).Log("msg", "downloaded index set at query time", "duration", duration) |
|
|
|
|
}() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -311,7 +314,7 @@ func (t *table) getOrCreateIndexSet(id string, forQuerying bool) (IndexSet, erro |
|
|
|
|
// EnsureQueryReadiness ensures that we have downloaded the common index as well as user index for the provided userIDs.
|
|
|
|
|
// When ensuring query readiness for a table, we will always download common index set because it can include index for one of the provided user ids.
|
|
|
|
|
func (t *table) EnsureQueryReadiness(ctx context.Context, userIDs []string) error { |
|
|
|
|
commonIndexSet, err := t.getOrCreateIndexSet("", false) |
|
|
|
|
commonIndexSet, err := t.getOrCreateIndexSet(ctx, "", false) |
|
|
|
|
if err != nil { |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
@ -339,7 +342,7 @@ func (t *table) EnsureQueryReadiness(ctx context.Context, userIDs []string) erro |
|
|
|
|
// downloadUserIndexes downloads user specific index files concurrently.
|
|
|
|
|
func (t *table) downloadUserIndexes(ctx context.Context, userIDs []string) error { |
|
|
|
|
return concurrency.ForEachJob(ctx, len(userIDs), maxDownloadConcurrency, func(ctx context.Context, idx int) error { |
|
|
|
|
indexSet, err := t.getOrCreateIndexSet(userIDs[idx], false) |
|
|
|
|
indexSet, err := t.getOrCreateIndexSet(ctx, userIDs[idx], false) |
|
|
|
|
if err != nil { |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|