From 9cddee94f80fb72539a9c16935274f9a1e255f05 Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Mon, 21 Nov 2022 18:38:50 +0100 Subject: [PATCH] console: fix selection of aggregate table on impossible resolution When requesting a too small resolution for data that are too far in the past, prefer to select a table with data than a table without. Previously, the resolution was a hard requirement. --- console/clickhouse.go | 24 +++++++++++++----------- console/clickhouse_test.go | 15 +++++++++++++++ console/data/docs/99-changelog.md | 1 + 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/console/clickhouse.go b/console/clickhouse.go index 6699ba9d..a30e6a2b 100644 --- a/console/clickhouse.go +++ b/console/clickhouse.go @@ -8,6 +8,7 @@ import ( "encoding/json" "errors" "fmt" + "sort" "strings" "text/template" "time" @@ -220,10 +221,12 @@ func (c *Component) getBestTable(start time.Time, targetInterval time.Duration) // We can use the consolidated data. The first // criteria is to find the tables matching the time // criteria. + fmt.Println(c.flowsTables) candidates := []int{} for idx, table := range c.flowsTables { if start.After(table.Oldest.Add(table.Resolution)) { candidates = append(candidates, idx) + fmt.Println(candidates) } } if len(candidates) == 0 { @@ -245,20 +248,19 @@ func (c *Component) getBestTable(start time.Time, targetInterval time.Duration) } } } - if len(candidates) > 1 { - // Use interval to find the best one - best := 0 - for _, idx := range candidates { - if c.flowsTables[idx].Resolution > targetInterval { - continue - } - if c.flowsTables[idx].Resolution > c.flowsTables[best].Resolution { - best = idx - } + sort.Slice(candidates, func(i, j int) bool { + return c.flowsTables[candidates[i]].Resolution < c.flowsTables[candidates[j]].Resolution + }) + // If possible, use the first resolution before the target interval + for len(candidates) > 1 { + if c.flowsTables[candidates[1]].Resolution < targetInterval { + candidates = candidates[1:] + } else { + break } - candidates = []int{best} } table = c.flowsTables[candidates[0]].Name + fmt.Println(table) computedInterval = c.flowsTables[candidates[0]].Resolution } if computedInterval < time.Second { diff --git a/console/clickhouse_test.go b/console/clickhouse_test.go index 59d137fc..2b95d731 100644 --- a/console/clickhouse_test.go +++ b/console/clickhouse_test.go @@ -270,6 +270,21 @@ func TestFinalizeQuery(t *testing.T) { Points: 720, }, Expected: `toStartOfInterval(TimeReceived + INTERVAL 50 second, INTERVAL 120 second) - INTERVAL 50 second`, + }, { + Description: "Small interval outside main table expiration", + Query: "SELECT InIfProvider FROM {{ .Table }}", + Tables: []flowsTable{ + {"flows", time.Duration(0), time.Date(2022, 11, 06, 12, 0, 0, 0, time.UTC)}, + {"flows_1h0m0s", time.Hour, time.Date(2022, 04, 25, 18, 0, 0, 0, time.UTC)}, + {"flows_1m0s", time.Minute, time.Date(2022, 11, 14, 12, 0, 0, 0, time.UTC)}, + {"flows_5m0s", 5 * time.Minute, time.Date(2022, 8, 23, 12, 0, 0, 0, time.UTC)}, + }, + Context: inputContext{ + Start: time.Date(2022, 10, 30, 1, 0, 0, 0, time.UTC), + End: time.Date(2022, 10, 30, 12, 0, 0, 0, time.UTC), + Points: 200, + }, + Expected: "SELECT InIfProvider FROM flows_5m0s", }, } diff --git a/console/data/docs/99-changelog.md b/console/data/docs/99-changelog.md index 50775d7d..a86ff6ca 100644 --- a/console/data/docs/99-changelog.md +++ b/console/data/docs/99-changelog.md @@ -21,6 +21,7 @@ details. - 🩹 *inlet*: handle non-fatal BMP decoding errors more gracefully - 🩹 *inlet*: fix a small memory leak in BMP collector +- 🩹 *console*: fix selection of the aggregate table to not get empty graphs - 🩹 *console*: use configured dimensions limit for “Visualize” tab - 🌱 *inlet*: optimize BMP collector (see above) - 🌱 *inlet*: replace LRU cache for classifiers by a time-based cache