api/prometheus/v1: merge envelope and payload JSON decode, fixes #977 - #2078
Open
felpau05 wants to merge 1 commit into
Open
api/prometheus/v1: merge envelope and payload JSON decode, fixes #977#2078felpau05 wants to merge 1 commit into
felpau05 wants to merge 1 commit into
Conversation
Removes the redundant second JSON parse across all 20 methods affected by prometheus#977. Decodes the envelope and typed payload in a single json.Unmarshal pass instead of an intermediate json.RawMessage that each method re-parsed separately. Changes apiResponse.Data from json.RawMessage to interface{}. Updates Do and DoGetFallback to take a new data interface{} destination. A typed pointer decodes directly via Go's existing behavior of following a non-nil pointer stored in an interface field. Passing nil falls back to the current json.RawMessage behavior unchanged (used by CleanTombstones and DeleteSeries). FormatQuery remains unconverted as it uses a raw string(body) cast rather than json.Unmarshal on the body. Fixes prometheus#977. Signed-off-by: felpau05 <felpau05@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #977.
Removes the redundant second JSON parse across all 20 methods affected by this issue, by decoding the response envelope and the typed payload in a single
json.Unmarshalpass instead of decoding into an intermediatejson.RawMessagethat each method then re-parsed separately.How
apiResponse.Datachanges fromjson.RawMessagetointerface{}.apiClient.Do/DoGetFallbacktake a newdata interface{}destination parameter. When a caller passes a typed pointer (e.g.&queryResult{}),json.Unmarshaldecodes directly into it via Go's existing behavior of following a non-nil pointer already stored in an interface field — no second parse. When a caller passesnil,Dofalls back to decoding into a localjson.RawMessageand returns it as[]byte, preserving the exact current behavior for any caller that only needs the raw bytes.CleanTombstonesandDeleteSeriesare unaffected — they never read the response body, so they already passnil.FormatQueryis intentionally not converted. It doesn't calljson.Unmarshalon the body at all — it does a rawstring(body)cast — so it was never affected by the double-parse this issue describes. While verifying this, I found what looks like a separate, pre-existing bug (the raw cast leaves JSON quoting/escaping in the returned string instead of decoding it) — filing that separately rather than mixing an unrelated behavior change into this PR.Why this is scoped differently from #1090
That attempt removed the buffering in
httpClient.Do(api/client.go) itself to stream fromresp.Body, which broke request cancellation handling and ended up with a benchmark that stopped measuring anything real. This PR doesn't touchapi/client.goor cancellation at all —Dostill receives a fully-buffered body exactly as before. The only change is not parsing that body twice.Benchmark
New, committed
BenchmarkQueryRangedrivingQueryRangethrough the public API over a real HTTP round trip, against a 100-series × 350-sample matrix response (~35k samples),-count=100,benchstat:RawMessagecopy and then reparses it; removing that copy is the whole effect.n=100) benchmark completely flattened the localhost HTTP round-trip noise, revealing a massive and highly consistent decode speedup.Tests
queryTeststable inTestAPIs, alongside the existing scalar case, assertingreflect.DeepEqualon the fully decodedmodel.Matrix— the path this change (and the benchmark) actually exercises. Confirmed the assertion catches regressions by manually corrupting the expected value and checking the test fails, then reverting.go build,go vet,gofmt -l ., andgo test -count=1 ./api/...are all clean.@kakkoyun — you triaged this issue originally; would appreciate a look when you have time.