This commit is contained in:
2026-06-10 06:18:45 +03:00
parent 4089ca40c9
commit 9ec86282ad
47 changed files with 3493 additions and 4502 deletions

View File

@@ -4,8 +4,8 @@ import (
"fmt"
"net"
diploma "gordenko.dev/dima/qb"
"gordenko.dev/dima/qb/bin"
bin "gordenko.dev/dima/bin/little"
"gordenko.dev/dima/qb"
"gordenko.dev/dima/qb/bufreader"
"gordenko.dev/dima/qb/proto"
)
@@ -33,7 +33,6 @@ func Connect(address string) (*Connection, error) {
if err != nil {
return nil, err
}
return &Connection{
conn: conn,
src: bufreader.New(conn, 1500),
@@ -51,22 +50,19 @@ func (s *Connection) Close() {
func (s *Connection) mustSuccess(reader *bufreader.BufferedReader) (err error) {
code, err := reader.ReadByte()
if err != nil {
return fmt.Errorf("read response code: %s", err)
return
}
switch code {
case proto.RespSuccess:
return nil // ok
case proto.RespError:
return s.onError()
default:
return fmt.Errorf("unknown reponse code %d", code)
}
}
func (s *Connection) AddMetric(req proto.AddMetricReq) error {
func (s *Connection) AddMetric(req proto.AddMetricReq) (err error) {
arr := []byte{
proto.TypeAddMetric,
0, 0, 0, 0, //
@@ -74,9 +70,9 @@ func (s *Connection) AddMetric(req proto.AddMetricReq) error {
byte(req.FracDigits),
}
bin.PutUint32(arr[1:], req.MetricID)
if _, err := s.conn.Write(arr); err != nil {
return err
// req
if _, err = s.conn.Write(arr); err != nil {
return
}
return s.mustSuccess(s.src)
}
@@ -96,52 +92,57 @@ func (s *Connection) AddMetric(req proto.AddMetricReq) error {
// return s.mustSuccess(s.src)
// }
func (s *Connection) GetMetric(metricID uint32) (*proto.Metric, error) {
func (s *Connection) GetMetric(metricID uint32) (_ *proto.Metric, err error) {
arr := []byte{
proto.TypeGetMetric,
0, 0, 0, 0,
}
bin.PutUint32(arr[1:], metricID)
if _, err := s.conn.Write(arr); err != nil {
return nil, err
// req
if _, err = s.conn.Write(arr); err != nil {
return
}
// answer
code, err := s.src.ReadByte()
if err != nil {
return nil, fmt.Errorf("read response code: %s", err)
return
}
switch code {
case proto.RespValue:
arr, err := s.src.ReadN(6)
var (
metric proto.Metric
metricType byte
)
metric.MetricID, err = bin.ReadUint32(s.src)
if err != nil {
return nil, fmt.Errorf("read body: %s", err)
return
}
return &proto.Metric{
MetricID: bin.GetUint32(arr),
MetricType: diploma.MetricType(arr[4]),
FracDigits: int(arr[5]),
}, nil
metricType, err = bin.ReadByte(s.src)
if err != nil {
return
}
metric.MetricType = qb.MetricType(metricType)
metric.FracDigits, err = bin.ReadByteAsInt(s.src)
if err != nil {
return
}
return &metric, nil
case proto.RespError:
return nil, s.onMaybeError()
default:
return nil, fmt.Errorf("unknown reponse code %d", code)
}
}
func (s *Connection) DeleteMetric(metricID uint32) error {
func (s *Connection) DeleteMetric(metricID uint32) (err error) {
arr := []byte{
proto.TypeDeleteMetric,
0, 0, 0, 0, //
}
bin.PutUint32(arr[1:], metricID)
if _, err := s.conn.Write(arr); err != nil {
return err
// req
if _, err = s.conn.Write(arr); err != nil {
return
}
return s.mustSuccess(s.src)
}
@@ -156,9 +157,9 @@ func (s *Connection) AppendMeasure(req proto.AppendMeasureReq) (err error) {
bin.PutUint32(arr[1:], req.MetricID)
bin.PutUint32(arr[5:], req.Timestamp)
bin.PutFloat64(arr[9:], req.Value)
if _, err := s.conn.Write(arr); err != nil {
return err
// req
if _, err = s.conn.Write(arr); err != nil {
return
}
return s.mustSuccess(s.src)
}
@@ -181,11 +182,10 @@ func (s *Connection) AppendMeasures(req proto.AppendMeasuresReq) (err error) {
bin.PutFloat64(arr[pos+4:], measure.Value)
pos += recordSize
}
if _, err := s.conn.Write(arr); err != nil {
return err
// req
if _, err = s.conn.Write(arr); err != nil {
return
}
//fmt.Printf("encode measures: %d\n", len(req.Measures))
return s.mustSuccess(s.src)
}
@@ -213,26 +213,26 @@ func (s *Connection) AppendMeasurePerMetric(list []proto.MetricMeasure) (_ []pro
bin.PutFloat64(arr[pos+8:], item.Value)
pos += recordSize
}
if _, err := s.conn.Write(arr); err != nil {
return nil, err
// req
if _, err = s.conn.Write(arr); err != nil {
return
}
// answer
code, err := s.src.ReadByte()
if err != nil {
return nil, fmt.Errorf("read response code: %s", err)
return
}
switch code {
case proto.RespValue:
var (
qty uint16
count int
appendErrors []proto.AppendError
)
qty, err = bin.ReadUint16(s.src)
count, err = bin.ReadUint16AsInt(s.src)
if err != nil {
return
}
for range qty {
for range count {
var ae proto.AppendError
ae.MetricID, err = bin.ReadUint32(s.src)
if err != nil {
@@ -245,70 +245,26 @@ func (s *Connection) AppendMeasurePerMetric(list []proto.MetricMeasure) (_ []pro
appendErrors = append(appendErrors, ae)
}
return appendErrors, nil
default:
return nil, fmt.Errorf("unknown reponse code %d", code)
}
}
func (s *Connection) ListAllInstantMeasures(metricID uint32) ([]proto.InstantMeasure, error) {
func (s *Connection) ListAllInstantMeasures(metricID uint32) (_ []proto.InstantMeasure, err error) {
arr := []byte{
proto.TypeListAllInstantMeasures,
0, 0, 0, 0, // metricID
}
bin.PutUint32(arr[1:], metricID)
if _, err := s.conn.Write(arr); err != nil {
return nil, err
}
var (
result []proto.InstantMeasure
tmp = make([]byte, 12)
)
for {
code, err := s.src.ReadByte()
if err != nil {
return nil, fmt.Errorf("read response code: %s", err)
}
//fmt.Printf("code: %d\n", code)
switch code {
case proto.RespPartOfValue:
q, err := bin.ReadUint32(s.src)
if err != nil {
return nil, fmt.Errorf("read records qty: %s", err)
}
//fmt.Printf("q: %d\n", q)
for i := range int(q) {
err = bin.ReadNInto(s.src, tmp)
if err != nil {
return nil, fmt.Errorf("read record #%d: %s", i, err)
}
result = append(result, proto.InstantMeasure{
Timestamp: bin.GetUint32(tmp),
Value: bin.GetFloat64(tmp[4:]),
})
}
case proto.RespEndOfValue:
return result, nil
case proto.RespError:
return nil, s.onError()
default:
return nil, fmt.Errorf("unknown reponse code %d", code)
}
// req
if _, err = s.conn.Write(arr); err != nil {
return
}
// answer
return s.readInstantMeasures()
}
func (s *Connection) ListInstantMeasures(req proto.ListInstantMeasuresReq) ([]proto.InstantMeasure, error) {
func (s *Connection) ListInstantMeasures(req proto.ListInstantMeasuresReq) (_ []proto.InstantMeasure, err error) {
arr := []byte{
proto.TypeListInstantMeasures,
0, 0, 0, 0, // metricID
@@ -318,118 +274,66 @@ func (s *Connection) ListInstantMeasures(req proto.ListInstantMeasuresReq) ([]pr
bin.PutUint32(arr[1:], req.MetricID)
bin.PutUint32(arr[5:], req.Since)
bin.PutUint32(arr[9:], req.Until)
if _, err := s.conn.Write(arr); err != nil {
return nil, err
// req
if _, err = s.conn.Write(arr); err != nil {
return
}
// answer
return s.readInstantMeasures()
}
var (
result []proto.InstantMeasure
tmp = make([]byte, 12)
)
func (s *Connection) readInstantMeasures() (_ []proto.InstantMeasure, err error) {
var result []proto.InstantMeasure
for {
code, err := s.src.ReadByte()
var code byte
code, err = bin.ReadByte(s.src)
if err != nil {
return nil, fmt.Errorf("read response code: %s", err)
}
switch code {
case proto.RespPartOfValue:
q, err := bin.ReadUint32(s.src)
var count int
count, err = bin.ReadUint32AsInt(s.src)
if err != nil {
return nil, fmt.Errorf("read records qty: %s", err)
}
for i := range int(q) {
err = bin.ReadNInto(s.src, tmp)
for range count {
var measure proto.InstantMeasure
measure.Timestamp, err = bin.ReadUint32(s.src)
if err != nil {
return nil, fmt.Errorf("read record #%d: %s", i, err)
return
}
result = append(result, proto.InstantMeasure{
Timestamp: bin.GetUint32(tmp),
Value: bin.GetFloat64(tmp[4:]),
})
measure.Value, err = bin.ReadFloat64(s.src)
if err != nil {
return
}
result = append(result, measure)
}
case proto.RespEndOfValue:
return result, nil
case proto.RespError:
return nil, s.onError()
default:
return nil, fmt.Errorf("unknown reponse code %d", code)
}
}
}
func (s *Connection) ListAllCumulativeMeasures(metricID uint32) ([]proto.CumulativeMeasure, error) {
func (s *Connection) ListAllCumulativeMeasures(metricID uint32) (_ []proto.CumulativeMeasure, err error) {
arr := []byte{
proto.TypeListAllCumulativeMeasures,
0, 0, 0, 0, // metricID
}
bin.PutUint32(arr[1:], metricID)
if _, err := s.conn.Write(arr); err != nil {
return nil, err
}
var (
result []proto.CumulativeMeasure
tmp = make([]byte, 20)
)
for {
code, err := s.src.ReadByte()
if err != nil {
return nil, fmt.Errorf("read response code: %s", err)
}
//fmt.Printf("code: %d\n", code)
switch code {
case proto.RespPartOfValue:
q, err := bin.ReadUint32(s.src)
if err != nil {
return nil, fmt.Errorf("read records qty: %s", err)
}
for i := range int(q) {
err = bin.ReadNInto(s.src, tmp)
if err != nil {
return nil, fmt.Errorf("read record #%d: %s", i, err)
}
//fmt.Printf("tmp: %d\n", tmp)
result = append(result, proto.CumulativeMeasure{
Timestamp: bin.GetUint32(tmp),
Value: bin.GetFloat64(tmp[4:]),
Total: bin.GetFloat64(tmp[12:]),
})
// pretty.PPrintln("measure", CumulativeMeasure{
// Timestamp: bin.GetUint32(tmp),
// Value: bin.GetFloat64(tmp[4:]),
// Total: bin.GetFloat64(tmp[12:]),
// })
}
case proto.RespEndOfValue:
return result, nil
case proto.RespError:
return nil, s.onError()
default:
return nil, fmt.Errorf("unknown reponse code %d", code)
}
// req
if _, err = s.conn.Write(arr); err != nil {
return
}
// answer
return s.readCumulativeMeasures()
}
func (s *Connection) ListCumulativeMeasures(req proto.ListCumulativeMeasuresReq) ([]proto.CumulativeMeasure, error) {
func (s *Connection) ListCumulativeMeasures(req proto.ListCumulativeMeasuresReq) (_ []proto.CumulativeMeasure, err error) {
arr := []byte{
proto.TypeListCumulativeMeasures,
0, 0, 0, 0, // metricID
@@ -439,55 +343,56 @@ func (s *Connection) ListCumulativeMeasures(req proto.ListCumulativeMeasuresReq)
bin.PutUint32(arr[1:], req.MetricID)
bin.PutUint32(arr[5:], req.Since)
bin.PutUint32(arr[9:], req.Until)
if _, err := s.conn.Write(arr); err != nil {
return nil, err
// req
if _, err = s.conn.Write(arr); err != nil {
return
}
// answer
return s.readCumulativeMeasures()
}
var (
result []proto.CumulativeMeasure
tmp = make([]byte, 20)
)
func (s *Connection) readCumulativeMeasures() (_ []proto.CumulativeMeasure, err error) {
var result []proto.CumulativeMeasure
for {
code, err := s.src.ReadByte()
var code byte
code, err = bin.ReadByte(s.src)
if err != nil {
return nil, fmt.Errorf("read response code: %s", err)
}
switch code {
case proto.RespPartOfValue:
q, err := bin.ReadUint32(s.src)
var count int
count, err = bin.ReadUint32AsInt(s.src)
if err != nil {
return nil, fmt.Errorf("read records qty: %s", err)
}
for i := range int(q) {
err = bin.ReadNInto(s.src, tmp)
for range count {
var measure proto.CumulativeMeasure
measure.Timestamp, err = bin.ReadUint32(s.src)
if err != nil {
return nil, fmt.Errorf("read record #%d: %s", i, err)
return
}
result = append(result, proto.CumulativeMeasure{
Timestamp: bin.GetUint32(tmp),
Value: bin.GetFloat64(tmp[4:]),
Total: bin.GetFloat64(tmp[12:]),
})
measure.Value, err = bin.ReadFloat64(s.src)
if err != nil {
return
}
measure.Total, err = bin.ReadFloat64(s.src)
if err != nil {
return
}
result = append(result, measure)
}
case proto.RespEndOfValue:
return result, nil
case proto.RespError:
return nil, s.onError()
default:
return nil, fmt.Errorf("unknown reponse code %d", code)
}
}
}
func (s *Connection) ListInstantPeriods(req proto.ListInstantPeriodsReq) ([]proto.InstantPeriod, error) {
func (s *Connection) ListInstantPeriods(req proto.ListInstantPeriodsReq) (_ []proto.InstantPeriod, err error) {
arr := []byte{
proto.TypeListInstantPeriods,
0, 0, 0, 0, // metricID
@@ -504,87 +409,70 @@ func (s *Connection) ListInstantPeriods(req proto.ListInstantPeriodsReq) ([]prot
bin.PutUint16(arr[9:], uint16(req.Until.Year))
arr[11] = byte(req.Until.Month)
arr[12] = byte(req.Until.Day)
if _, err := s.conn.Write(arr); err != nil {
return nil, err
// req
if _, err = s.conn.Write(arr); err != nil {
return
}
var q int
if (req.AggregateFuncs & diploma.AggregateMin) == diploma.AggregateMin {
q++
}
if (req.AggregateFuncs & diploma.AggregateMax) == diploma.AggregateMax {
q++
}
if (req.AggregateFuncs & diploma.AggregateAvg) == diploma.AggregateAvg {
q++
}
var (
result []proto.InstantPeriod
// 12 bytes - period, since, until
// q * 8 bytes - min, max, avg
tmp = make([]byte, 12+q*8)
)
// answer
var result []proto.InstantPeriod
for {
code, err := s.src.ReadByte()
var code byte
code, err = s.src.ReadByte()
if err != nil {
return nil, fmt.Errorf("read response code: %s", err)
return
}
//fmt.Printf("code: %d\n", code)
switch code {
case proto.RespPartOfValue:
q, err := bin.ReadUint32(s.src)
var count int
count, err = bin.ReadUint32AsInt(s.src)
if err != nil {
return nil, fmt.Errorf("read records qty: %s", err)
return
}
for i := range int(q) {
err = bin.ReadNInto(s.src, tmp)
for range count {
var p proto.InstantPeriod
p.Period, err = bin.ReadUint32(s.src)
if err != nil {
return nil, fmt.Errorf("read record #%d: %s", i, err)
return
}
var (
p = proto.InstantPeriod{
Period: bin.GetUint32(tmp[0:]),
Since: bin.GetUint32(tmp[4:]),
Until: bin.GetUint32(tmp[8:]),
p.Since, err = bin.ReadUint32(s.src)
if err != nil {
return
}
p.Until, err = bin.ReadUint32(s.src)
if err != nil {
return
}
if (req.AggregateFuncs & qb.AggregateMin) == qb.AggregateMin {
p.Min, err = bin.ReadFloat64(s.src)
if err != nil {
return
}
// 12 bytes - period, since, until
pos = 12
)
if (req.AggregateFuncs & diploma.AggregateMin) == diploma.AggregateMin {
p.Min = bin.GetFloat64(tmp[pos:])
pos += 8
}
if (req.AggregateFuncs & diploma.AggregateMax) == diploma.AggregateMax {
p.Max = bin.GetFloat64(tmp[pos:])
pos += 8
if (req.AggregateFuncs & qb.AggregateMax) == qb.AggregateMax {
p.Max, err = bin.ReadFloat64(s.src)
if err != nil {
return
}
}
if (req.AggregateFuncs & diploma.AggregateAvg) == diploma.AggregateAvg {
p.Avg = bin.GetFloat64(tmp[pos:])
if (req.AggregateFuncs & qb.AggregateAvg) == qb.AggregateAvg {
p.Avg, err = bin.ReadFloat64(s.src)
if err != nil {
return
}
}
result = append(result, p)
}
case proto.RespEndOfValue:
return result, nil
case proto.RespError:
return nil, s.onError()
default:
return nil, fmt.Errorf("unknown reponse code %d", code)
}
}
}
func (s *Connection) ListCumulativePeriods(req proto.ListCumulativePeriodsReq) ([]proto.CumulativePeriod, error) {
func (s *Connection) ListCumulativePeriods(req proto.ListCumulativePeriodsReq) (_ []proto.CumulativePeriod, err error) {
arr := []byte{
proto.TypeListCumulativePeriods,
0, 0, 0, 0, // metricID
@@ -600,108 +488,107 @@ func (s *Connection) ListCumulativePeriods(req proto.ListCumulativePeriodsReq) (
bin.PutUint16(arr[9:], uint16(req.Until.Year))
arr[11] = byte(req.Until.Month)
arr[12] = byte(req.Until.Day)
if _, err := s.conn.Write(arr); err != nil {
return nil, err
// req
if _, err = s.conn.Write(arr); err != nil {
return
}
var (
result []proto.CumulativePeriod
tmp = make([]byte, 28)
)
// answer
var result []proto.CumulativePeriod
for {
code, err := s.src.ReadByte()
var code byte
code, err = s.src.ReadByte()
if err != nil {
return nil, fmt.Errorf("read response code: %s", err)
return
}
switch code {
case proto.RespPartOfValue:
q, err := bin.ReadUint32(s.src)
var count int
count, err = bin.ReadUint32AsInt(s.src)
if err != nil {
return nil, fmt.Errorf("read records qty: %s", err)
return
}
for i := range int(q) {
err = bin.ReadNInto(s.src, tmp)
for range count {
var p proto.CumulativePeriod
p.Period, err = bin.ReadUint32(s.src)
if err != nil {
return nil, fmt.Errorf("read record #%d: %s", i, err)
return
}
result = append(result, proto.CumulativePeriod{
Period: bin.GetUint32(tmp[0:]),
Since: bin.GetUint32(tmp[4:]),
Until: bin.GetUint32(tmp[8:]),
EndValue: bin.GetFloat64(tmp[12:]),
Total: bin.GetFloat64(tmp[20:]),
})
p.Since, err = bin.ReadUint32(s.src)
if err != nil {
return
}
p.Until, err = bin.ReadUint32(s.src)
if err != nil {
return
}
p.EndValue, err = bin.ReadFloat64(s.src)
if err != nil {
return
}
p.Total, err = bin.ReadFloat64(s.src)
if err != nil {
return
}
result = append(result, p)
}
case proto.RespEndOfValue:
return result, nil
case proto.RespError:
return nil, s.onError()
default:
return nil, fmt.Errorf("unknown reponse code %d", code)
}
}
}
func (s *Connection) ListCurrentValues(metricIDs []uint32) ([]proto.CurrentValue, error) {
func (s *Connection) ListCurrentValues(metricIDs []uint32) (_ []proto.CurrentValue, err error) {
arr := make([]byte, 3+metricKeySize*len(metricIDs))
arr[0] = proto.TypeListCurrentValues
bin.PutUint16(arr[1:], uint16(len(metricIDs)))
off := 3
for _, metricID := range metricIDs {
bin.PutUint32(arr[off:], metricID)
off += metricKeySize
}
if _, err := s.conn.Write(arr); err != nil {
return nil, err
// req
if _, err = s.conn.Write(arr); err != nil {
return
}
var (
result []proto.CurrentValue
tmp = make([]byte, 16)
)
// answer
var result []proto.CurrentValue
for {
code, err := s.src.ReadByte()
var code byte
code, err = s.src.ReadByte()
if err != nil {
return nil, fmt.Errorf("read response code: %s", err)
return
}
switch code {
case proto.RespPartOfValue:
q, err := bin.ReadUint32(s.src)
var count int
count, err = bin.ReadUint32AsInt(s.src)
if err != nil {
return nil, fmt.Errorf("read records qty: %s", err)
return
}
for i := range int(q) {
err = bin.ReadNInto(s.src, tmp)
for range count {
var m proto.CurrentValue
m.MetricID, err = bin.ReadUint32(s.src)
if err != nil {
return nil, fmt.Errorf("read record #%d: %s", i, err)
return
}
result = append(result, proto.CurrentValue{
MetricID: bin.GetUint32(tmp),
Timestamp: bin.GetUint32(tmp[4:]),
Value: bin.GetFloat64(tmp[8:]),
})
m.Timestamp, err = bin.ReadUint32(s.src)
if err != nil {
return
}
m.Value, err = bin.ReadFloat64(s.src)
if err != nil {
return
}
result = append(result, m)
}
case proto.RespEndOfValue:
return result, nil
case proto.RespError:
return nil, s.onError()
default:
return nil, fmt.Errorf("unknown reponse code %d", code)
}
@@ -716,7 +603,7 @@ func (s *Connection) DeleteMeasures(req proto.DeleteMeasuresReq) (err error) {
}
bin.PutUint32(arr[1:], req.MetricID)
bin.PutUint32(arr[5:], req.Since)
// req
if _, err := s.conn.Write(arr); err != nil {
return err
}