Files
traces/pkg/model/v1/segment_decoder.go
Javier Molina ReyesandGitHub a7dde3a25b feat: Allow partial traces to be returned (#3941)
* enable return partial traces

* fix bug returning an error on max size reached

* test combiner with partial trace

* allow partial traces to be returned from the ingester

* add message to TraceByIdV2 on partial trace returned

* fix test and move allowtraces one level down

* allow partial traces in segment decoder

* fix compilation error

* use an enum to describe better the trace response

* revert segment decoder changes

* do not check the trace size at block level

* changelog

* move short-circuit to the top of the method

* simplify partial trace logic

* added missing changelog

* perf improvement by not processing partial traces from queriers

* do not replace the trace every time

* flag when querier returns a partial trace

* fix proto
2024-08-26 14:06:39 -04:00

58 lines
1.5 KiB
Go

package v1
import (
"fmt"
"github.com/gogo/protobuf/proto"
"github.com/grafana/tempo/pkg/model/decoder"
"github.com/grafana/tempo/pkg/model/trace"
"github.com/grafana/tempo/pkg/tempopb"
)
type SegmentDecoder struct{}
var segmentDecoder = &SegmentDecoder{}
// NewSegmentDecoder() returns a v1 segment decoder.
func NewSegmentDecoder() *SegmentDecoder {
return segmentDecoder
}
func (d *SegmentDecoder) PrepareForWrite(trace *tempopb.Trace, _, _ uint32) ([]byte, error) {
// v1 encoding doesn't support start/end
return proto.Marshal(trace)
}
func (d *SegmentDecoder) PrepareForRead(segments [][]byte) (*tempopb.Trace, error) {
// each slice is a marshalled tempopb.Trace, unmarshal and combine
combiner := trace.NewCombiner(0, false)
for i, s := range segments {
t := &tempopb.Trace{}
err := proto.Unmarshal(s, t)
if err != nil {
return nil, fmt.Errorf("error unmarshaling trace: %w", err)
}
_, err = combiner.ConsumeWithFinal(t, i == len(segments)-1)
if err != nil {
return nil, fmt.Errorf("error combining trace: %w", err)
}
}
combinedTrace, _ := combiner.Result()
return combinedTrace, nil
}
func (d *SegmentDecoder) ToObject(segments [][]byte) ([]byte, error) {
// wrap byte slices in a tempopb.TraceBytes and marshal
wrapper := &tempopb.TraceBytes{
Traces: append([][]byte(nil), segments...),
}
return proto.Marshal(wrapper)
}
func (d *SegmentDecoder) FastRange([]byte) (uint32, uint32, error) {
return 0, 0, decoder.ErrUnsupported
}