Skip to content

Commit fd8d1e6

Browse files
authored
Merge pull request #626 from metrico/chore/json-iterator-building
Chore/json iterator refactor
2 parents 48a0a66 + 21245e4 commit fd8d1e6

6 files changed

+510
-90
lines changed

.github/workflows/node-clickhouse-cluster.js.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ name: QRYN CI CLUSTER
44

55
on:
66
push:
7-
branches: [ master ]
7+
branches: [ master, gigapipe ]
88
paths-ignore:
99
- '**.md'
1010
- '**.yml'
1111
- '**.yaml'
1212
pull_request:
13-
branches: [ master ]
13+
branches: [ master, gigapipe ]
1414
paths-ignore:
1515
- '**.md'
1616
- '**.yml'

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
/.idea/
2+
*.idx
3+
/docker

reader/controller/miscController.go

+25-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package controllerv1
22

33
import (
4-
"fmt"
4+
jsoniter "github.com/json-iterator/go"
55
"github.com/metrico/qryn/reader/utils/logger"
66
watchdog "github.com/metrico/qryn/reader/watchdog"
77
"net/http"
@@ -41,7 +41,30 @@ func (uc *MiscController) Metadata(w http.ResponseWriter, r *http.Request) {
4141
}
4242

4343
func (uc *MiscController) Buildinfo(w http.ResponseWriter, r *http.Request) {
44+
//w.Header().Set("Content-Type", "application/json")
45+
//w.WriteHeader(http.StatusOK)
46+
//w.Write([]byte(fmt.Sprintf(`{"status": "success","data": {"version": "%s"}}`, uc.Version)))
47+
4448
w.Header().Set("Content-Type", "application/json")
4549
w.WriteHeader(http.StatusOK)
46-
w.Write([]byte(fmt.Sprintf(`{"status": "success","data": {"version": "%s"}}`, uc.Version)))
50+
51+
json := jsoniter.ConfigFastest
52+
stream := json.BorrowStream(nil)
53+
defer json.ReturnStream(stream)
54+
stream.WriteObjectStart()
55+
stream.WriteObjectField("status")
56+
stream.WriteString("success")
57+
stream.WriteMore()
58+
59+
stream.WriteObjectField("data")
60+
stream.WriteObjectStart()
61+
62+
stream.WriteObjectField("version")
63+
stream.WriteString(uc.Version)
64+
65+
stream.WriteObjectEnd()
66+
stream.WriteObjectEnd()
67+
68+
w.Write(stream.Buffer())
69+
4770
}

reader/controller/promQueryRangeController.go

+173-18
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
"github.com/gofiber/fiber/v2"
66
"github.com/gorilla/schema"
7+
jsoniter "github.com/json-iterator/go"
78
"github.com/metrico/qryn/reader/service"
89
"github.com/metrico/qryn/reader/utils/logger"
910
"github.com/pkg/errors"
@@ -161,34 +162,98 @@ func parseQueryRangeProps(ctx *fiber.Ctx) (QueryRangeProps, error) {
161162
return res, err
162163
}
163164

165+
//func PromError(code int, msg string, w http.ResponseWriter) {
166+
// w.WriteHeader(code)
167+
// w.Header().Set("Content-Type", "application/json")
168+
// w.Write([]byte(fmt.Sprintf(`{"status": "error", "errorType":"error", "error": %s}`,
169+
// strconv.Quote(msg))))
170+
//}
171+
164172
func PromError(code int, msg string, w http.ResponseWriter) {
165173
w.WriteHeader(code)
166174
w.Header().Set("Content-Type", "application/json")
167-
w.Write([]byte(fmt.Sprintf(`{"status": "error", "errorType":"error", "error": %s}`,
168-
strconv.Quote(msg))))
175+
176+
json := jsoniter.ConfigFastest
177+
stream := json.BorrowStream(nil)
178+
defer json.ReturnStream(stream)
179+
180+
stream.WriteObjectStart()
181+
stream.WriteObjectField("status")
182+
stream.WriteString("error")
183+
stream.WriteMore()
184+
stream.WriteObjectField("errorType")
185+
stream.WriteString("error")
186+
stream.WriteMore()
187+
stream.WriteObjectField("error")
188+
stream.WriteString(msg)
189+
stream.WriteObjectEnd()
190+
191+
w.Write(stream.Buffer())
169192
}
170193

194+
//func writeResponse(res *promql.Result, w http.ResponseWriter) error {
195+
// var err error
196+
// w.Header().Set("Content-Type", "application/json")
197+
// _, err = w.Write([]byte(fmt.Sprintf(`{"status" : "success", "data" : {"resultType" : "%s", "result" : [`,
198+
// res.Value.Type())))
199+
// if err != nil {
200+
// return err
201+
// }
202+
// switch res.Value.(type) {
203+
// case promql.Matrix:
204+
// err = writeMatrix(res, w)
205+
// break
206+
// case promql.Vector:
207+
// err = writeVector(res, w)
208+
// break
209+
// case promql.Scalar:
210+
// err = writeScalar(res, w)
211+
// }
212+
// if err != nil {
213+
// return err
214+
// }
215+
// w.Write([]byte("]}}"))
216+
// return nil
217+
//}
218+
171219
func writeResponse(res *promql.Result, w http.ResponseWriter) error {
172-
var err error
173220
w.Header().Set("Content-Type", "application/json")
174-
_, err = w.Write([]byte(fmt.Sprintf(`{"status" : "success", "data" : {"resultType" : "%s", "result" : [`,
175-
res.Value.Type())))
221+
222+
json := jsoniter.ConfigFastest
223+
stream := json.BorrowStream(nil)
224+
defer json.ReturnStream(stream)
225+
226+
stream.WriteObjectStart()
227+
stream.WriteObjectField("status")
228+
stream.WriteString("success")
229+
stream.WriteMore()
230+
stream.WriteObjectField("data")
231+
stream.WriteObjectStart()
232+
stream.WriteObjectField("resultType")
233+
stream.WriteString(string(res.Value.Type()))
234+
stream.WriteMore()
235+
stream.WriteObjectField("result")
236+
stream.WriteArrayStart()
237+
238+
_, err := w.Write(stream.Buffer())
176239
if err != nil {
177240
return err
178241
}
242+
stream.Reset(nil)
243+
179244
switch res.Value.(type) {
180245
case promql.Matrix:
181246
err = writeMatrix(res, w)
182-
break
183247
case promql.Vector:
184248
err = writeVector(res, w)
185-
break
186249
case promql.Scalar:
187250
err = writeScalar(res, w)
188251
}
252+
189253
if err != nil {
190254
return err
191255
}
256+
192257
w.Write([]byte("]}}"))
193258
return nil
194259
}
@@ -199,46 +264,136 @@ func writeScalar(res *promql.Result, w http.ResponseWriter) error {
199264
return nil
200265
}
201266

267+
// func writeMatrix(res *promql.Result, w http.ResponseWriter) error {
268+
// val := res.Value.(promql.Matrix)
269+
// for i, s := range val {
270+
// if i > 0 {
271+
// w.Write([]byte(","))
272+
// }
273+
// w.Write([]byte(`{"metric": {`))
274+
// for j, v := range s.Metric {
275+
// if j > 0 {
276+
// w.Write([]byte(","))
277+
// }
278+
// w.Write([]byte(fmt.Sprintf("%s:%s", strconv.Quote(v.Name), strconv.Quote(v.Value))))
279+
// }
280+
// w.Write([]byte(`},"values": [`))
281+
// for j, v := range s.Points {
282+
// if j > 0 {
283+
// w.Write([]byte(","))
284+
// }
285+
// w.Write([]byte(fmt.Sprintf(`[%f,"%f"]`, float64(v.T)/1000, v.V)))
286+
// }
287+
// w.Write([]byte("]}"))
288+
// }
289+
// return nil
290+
// }
202291
func writeMatrix(res *promql.Result, w http.ResponseWriter) error {
203292
val := res.Value.(promql.Matrix)
293+
294+
json := jsoniter.ConfigFastest
295+
204296
for i, s := range val {
205297
if i > 0 {
206298
w.Write([]byte(","))
207299
}
208-
w.Write([]byte(`{"metric": {`))
300+
301+
stream := json.BorrowStream(nil)
302+
303+
stream.WriteObjectStart()
304+
stream.WriteObjectField("metric")
305+
stream.WriteObjectStart()
306+
209307
for j, v := range s.Metric {
210308
if j > 0 {
211-
w.Write([]byte(","))
309+
stream.WriteMore()
212310
}
213-
w.Write([]byte(fmt.Sprintf("%s:%s", strconv.Quote(v.Name), strconv.Quote(v.Value))))
311+
stream.WriteObjectField(v.Name)
312+
stream.WriteString(v.Value)
214313
}
215-
w.Write([]byte(`},"values": [`))
314+
315+
stream.WriteObjectEnd()
316+
stream.WriteMore()
317+
stream.WriteObjectField("values")
318+
stream.WriteArrayStart()
319+
216320
for j, v := range s.Points {
217321
if j > 0 {
218-
w.Write([]byte(","))
322+
stream.WriteMore()
219323
}
220-
w.Write([]byte(fmt.Sprintf(`[%f,"%f"]`, float64(v.T)/1000, v.V)))
324+
stream.WriteArrayStart()
325+
stream.WriteFloat64(float64(v.T) / 1000)
326+
stream.WriteMore()
327+
stream.WriteString(strconv.FormatFloat(v.V, 'f', -1, 64))
328+
stream.WriteArrayEnd()
221329
}
222-
w.Write([]byte("]}"))
330+
331+
stream.WriteArrayEnd()
332+
stream.WriteObjectEnd()
333+
334+
w.Write(stream.Buffer())
335+
json.ReturnStream(stream)
223336
}
337+
224338
return nil
225339
}
226340

341+
//func writeVector(res *promql.Result, w http.ResponseWriter) error {
342+
// val := res.Value.(promql.Vector)
343+
// for i, s := range val {
344+
// if i > 0 {
345+
// w.Write([]byte(","))
346+
// }
347+
// w.Write([]byte(`{"metric":{`))
348+
// for j, lbl := range s.Metric {
349+
// if j > 0 {
350+
// w.Write([]byte(","))
351+
// }
352+
// w.Write([]byte(fmt.Sprintf("%s:%s", strconv.Quote(lbl.Name), strconv.Quote(lbl.Value))))
353+
// }
354+
// w.Write([]byte(fmt.Sprintf(`},"value":[%f,"%f"]}`, float64(s.T/1000), s.V)))
355+
// }
356+
// return nil
357+
//}
358+
227359
func writeVector(res *promql.Result, w http.ResponseWriter) error {
228360
val := res.Value.(promql.Vector)
361+
362+
json := jsoniter.ConfigFastest
363+
229364
for i, s := range val {
230365
if i > 0 {
231366
w.Write([]byte(","))
232367
}
233-
w.Write([]byte(`{"metric":{`))
368+
369+
stream := json.BorrowStream(nil)
370+
371+
stream.WriteObjectStart()
372+
stream.WriteObjectField("metric")
373+
stream.WriteObjectStart()
374+
234375
for j, lbl := range s.Metric {
235376
if j > 0 {
236-
w.Write([]byte(","))
377+
stream.WriteMore()
237378
}
238-
w.Write([]byte(fmt.Sprintf("%s:%s", strconv.Quote(lbl.Name), strconv.Quote(lbl.Value))))
379+
stream.WriteObjectField(lbl.Name)
380+
stream.WriteString(lbl.Value)
239381
}
240-
w.Write([]byte(fmt.Sprintf(`},"value":[%f,"%f"]}`, float64(s.T/1000), s.V)))
382+
383+
stream.WriteObjectEnd()
384+
stream.WriteMore()
385+
stream.WriteObjectField("value")
386+
stream.WriteArrayStart()
387+
stream.WriteFloat64(float64(s.T) / 1000)
388+
stream.WriteMore()
389+
stream.WriteString(strconv.FormatFloat(s.V, 'f', -1, 64))
390+
stream.WriteArrayEnd()
391+
stream.WriteObjectEnd()
392+
393+
w.Write(stream.Buffer())
394+
json.ReturnStream(stream)
241395
}
396+
242397
return nil
243398
}
244399

reader/controller/queryRangeController.go

+43-5
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ package controllerv1
22

33
import (
44
"context"
5-
"fmt"
65
"github.com/gorilla/websocket"
6+
jsoniter "github.com/json-iterator/go"
77
"github.com/metrico/qryn/reader/model"
88
"github.com/metrico/qryn/reader/service"
99
"net/http"
@@ -75,10 +75,48 @@ func (q *QueryRangeController) Query(w http.ResponseWriter, r *http.Request) {
7575
}
7676
if query == "vector(1)+vector(1)" {
7777
w.Header().Set("Content-Type", "application/json")
78-
w.Write([]byte(fmt.Sprintf(`{"status": "success", "data": {"resultType": "vector", "result": [{
79-
"metric": {},
80-
"value": [%d, "2"]
81-
}]}}`, time.Now().Unix())))
78+
json := jsoniter.ConfigFastest
79+
stream := json.BorrowStream(nil)
80+
defer json.ReturnStream(stream)
81+
82+
stream.WriteObjectStart()
83+
stream.WriteObjectField("status")
84+
stream.WriteString("success")
85+
stream.WriteMore()
86+
87+
stream.WriteObjectField("data")
88+
stream.WriteObjectStart()
89+
90+
stream.WriteObjectField("resultType")
91+
stream.WriteString("vector")
92+
stream.WriteMore()
93+
94+
stream.WriteObjectField("result")
95+
stream.WriteArrayStart()
96+
97+
stream.WriteObjectStart()
98+
stream.WriteObjectField("metric")
99+
stream.WriteEmptyObject()
100+
stream.WriteMore()
101+
102+
stream.WriteObjectField("value")
103+
stream.WriteArrayStart()
104+
stream.WriteInt64(time.Now().Unix()) // Unix timestamp
105+
stream.WriteMore()
106+
stream.WriteString("2")
107+
stream.WriteArrayEnd()
108+
109+
stream.WriteObjectEnd() // End of result object
110+
stream.WriteArrayEnd() // End of result array
111+
112+
stream.WriteObjectEnd() // End of data object
113+
stream.WriteObjectEnd() // End of main object
114+
115+
w.Write(stream.Buffer())
116+
//w.Write([]byte(fmt.Sprintf(`{"status": "success", "data": {"resultType": "vector", "result": [{
117+
// "metric": {},
118+
// "value": [%d, "2"]
119+
//}]}}`, time.Now().Unix())))
82120
return
83121
}
84122
iTime, err := getRequiredI64(r, "time", "0", nil)

0 commit comments

Comments
 (0)