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

carbonserver: include a Limited signal in /list_query api result #459

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 11 additions & 3 deletions carbonserver/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package carbonserver
import (
"encoding/json"
"fmt"
"log"
"net/http"
_ "net/http/pprof"
"strconv"
Expand Down Expand Up @@ -143,6 +142,8 @@ type ListQueryResult struct {
PhysicalSize int64
LogicalSize int64

Limited bool

Metrics []ListMetricInfo
}

Expand All @@ -156,14 +157,21 @@ func (listener *CarbonserverListener) queryMetricsList(query string, limit int,
return nil, errMetricsListEmpty
}

log.Println(strings.ReplaceAll(query, ".", "/"))
names, isFiles, nodes, err := fidx.trieIdx.query(strings.ReplaceAll(query, ".", "/"), limit, nil)
// TODO: support topk queries?

names, isFiles, nodes, limited, err := fidx.trieIdx.query(strings.ReplaceAll(query, ".", "/"), limit, nil)
if err != nil {
return nil, err
}
// WHY: it's impossible for /list_query api user to be aware that a
// query is limited in nodes lookup.
// Returning a Limited signal allows api user to decide that if it should
// make a separate a call or show a warning.
result.Limited = limited

for i, name := range names {
if len(result.Metrics) >= limit {
result.Limited = true
break
}

Expand Down
19 changes: 12 additions & 7 deletions carbonserver/trie.go
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,7 @@ func (ti *trieIndex) newDir() *trieNode {

// TODO: add some defensive logics agains bad queries?
// depth first search
func (ti *trieIndex) query(expr string, limit int, expand func(globs []string) ([]string, error)) (files []string, isFiles []bool, nodes []*trieNode, err error) {
func (ti *trieIndex) query(expr string, limit int, expand func(globs []string) ([]string, error)) (files []string, isFiles []bool, nodes []*trieNode, limited bool, err error) {
expr = strings.TrimSpace(expr)
if expr == "" {
expr = "*"
Expand All @@ -708,14 +708,14 @@ func (ti *trieIndex) query(expr string, limit int, expand func(globs []string) (
}
gs, err := newGlobState(node, expand)
if err != nil {
return nil, nil, nil, err
return nil, nil, nil, false, err
}
exact = exact && gs.exact
matchers = append(matchers, gs)
}

if len(matchers) == 0 {
return nil, nil, nil, nil
return nil, nil, nil, false, nil
}

var cur = ti.root
Expand Down Expand Up @@ -829,7 +829,12 @@ func (ti *trieIndex) query(expr string, limit int, expand func(globs []string) (
nodes = append(nodes, dirNode)
}

if len(files) >= limit || exact {
if len(files) >= limit {
limited = true
break
}

if exact {
break
}

Expand Down Expand Up @@ -861,7 +866,7 @@ func (ti *trieIndex) query(expr string, limit int, expand func(globs []string) (
continue
}

return files, isFiles, nodes, nil
return files, isFiles, nodes, limited, nil
}

// note: tn might be a root or file node, which has a nil c
Expand Down Expand Up @@ -1475,7 +1480,7 @@ func (listener *CarbonserverListener) expandGlobsTrie(query string) ([]string, [
var leafs []bool

for _, g := range globs {
f, l, _, err := fidx.trieIdx.query(g, listener.maxMetricsGlobbed-len(files), listener.expandGlobBraces)
f, l, _, _, err := fidx.trieIdx.query(g, listener.maxMetricsGlobbed-len(files), listener.expandGlobBraces)
if err != nil {
return nil, nil, err
}
Expand Down Expand Up @@ -1655,7 +1660,7 @@ func (ti *trieIndex) applyQuotas(resetFrequency time.Duration, quotas ...*Quota)
continue
}

paths, _, nodes, err := ti.query(strings.ReplaceAll(quota.Pattern, ".", "/"), 1<<31-1, nil)
paths, _, nodes, _, err := ti.query(strings.ReplaceAll(quota.Pattern, ".", "/"), 1<<31-1, nil)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion carbonserver/trie_fuzz_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ var trie = func() *trieIndex {
}()

func Fuzz(data []byte) int {
_, _, err := trie.query(string(data), 1000, func([]string) ([]string, error) { return nil, nil })
_, _,_, _, err := trie.query(string(data), 1000, func([]string) ([]string, error) { return nil, nil })
if err != nil {
// panic(err)
return 0
Expand Down
6 changes: 3 additions & 3 deletions carbonserver/trie_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,7 @@ func TestTrieIndex(t *testing.T) {
func TestTrieEdgeCases(t *testing.T) {
var trie = newTrie(".wsp", nil)

_, _, _, err := trie.query("[\xff\xff-\xff", 1000, func([]string) ([]string, error) { return nil, nil })
_, _, _, _, err := trie.query("[\xff\xff-\xff", 1000, func([]string) ([]string, error) { return nil, nil })
if err == nil || err.Error() != "glob: range overflow" {
t.Errorf("trie should return an range overflow error")
}
Expand Down Expand Up @@ -775,7 +775,7 @@ func TestTrieQueryOpts(t *testing.T) {
"sys.app.host-02.cpu.system",
}

files, _, nodes, err := trieIndex.query("sys/app/host-0{1,2}", 1000, nil)
files, _, nodes, _, err := trieIndex.query("sys/app/host-0{1,2}", 1000, nil)
if err != nil {
t.Error(err)
}
Expand Down Expand Up @@ -837,7 +837,7 @@ func TestTrieConcurrentReadWrite(t *testing.T) {
// case <-filec:
default:
// skipcq: GSC-G404
files, _, _, err := trieIndex.query(fmt.Sprintf("level-0-%d/level-1-%d/level-2-%d*", rand.Intn(factor), rand.Intn(factor), rand.Intn(factor)), int(math.MaxInt64), nil)
files, _, _, _, err := trieIndex.query(fmt.Sprintf("level-0-%d/level-1-%d/level-2-%d*", rand.Intn(factor), rand.Intn(factor), rand.Intn(factor)), int(math.MaxInt64), nil)
if err != nil {
panic(err)
}
Expand Down