| 85 | } |
| 86 | |
| 87 | func splitQuery(r tripperware.Request, interval time.Duration) ([]tripperware.Request, error) { |
| 88 | // If Start == end we should just run the original request |
| 89 | if r.GetStart() == r.GetEnd() { |
| 90 | return []tripperware.Request{r}, nil |
| 91 | } |
| 92 | |
| 93 | // Replace @ modifier function to their respective constant values in the query. |
| 94 | // This way subqueries will be evaluated at the same time as the parent query. |
| 95 | query, err := evaluateAtModifierFunction(r.GetQuery(), r.GetStart(), r.GetEnd()) |
| 96 | if err != nil { |
| 97 | return nil, err |
| 98 | } |
| 99 | var reqs []tripperware.Request |
| 100 | for start := r.GetStart(); start < r.GetEnd(); start = nextIntervalBoundary(start, r.GetStep(), interval) + r.GetStep() { |
| 101 | end := nextIntervalBoundary(start, r.GetStep(), interval) |
| 102 | if end+r.GetStep() >= r.GetEnd() { |
| 103 | end = r.GetEnd() |
| 104 | } |
| 105 | |
| 106 | reqs = append(reqs, r.WithQuery(query).WithStartEnd(start, end)) |
| 107 | } |
| 108 | return reqs, nil |
| 109 | } |
| 110 | |
| 111 | // evaluateAtModifierFunction parse the query and evaluates the `start()` and `end()` at modifier functions into actual constant timestamps. |
| 112 | // For example given the start of the query is 10.00, `http_requests_total[1h] @ start()` query will be replaced with `http_requests_total[1h] @ 10.00` |