diff --git a/CHANGELOG.md b/CHANGELOG.md index 06e9bcda974..073ef899045 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ### Changed +- For tracestate's members, prepend the new element and remove the oldest one, which is over capacity (#2592) - Add event and link drop counts to the exported data from the `oltptrace` exporter. (#2601) ### Fixed diff --git a/trace/tracestate.go b/trace/tracestate.go index 86fc62c1d8f..7b7af6955f9 100644 --- a/trace/tracestate.go +++ b/trace/tracestate.go @@ -171,7 +171,8 @@ func (ts TraceState) Get(key string) string { // specification an error is returned with the original TraceState. // // If adding a new list-member means the TraceState would have more members -// than is allowed an error is returned instead with the original TraceState. +// then is allowed, the new list-member will be inserted and the right-most +// list-member will be dropped in the returned TraceState. func (ts TraceState) Insert(key, value string) (TraceState, error) { m, err := newMember(key, value) if err != nil { @@ -179,17 +180,10 @@ func (ts TraceState) Insert(key, value string) (TraceState, error) { } cTS := ts.Delete(key) - if cTS.Len()+1 > maxListMembers { - // TODO (MrAlias): When the second version of the Trace Context - // specification is published this needs to not return an error. - // Instead it should drop the "right-most" member and insert the new - // member at the front. - // - // https://github.com/w3c/trace-context/pull/448 - return ts, fmt.Errorf("failed to insert: %w", errMemberNumber) + if cTS.Len()+1 <= maxListMembers { + cTS.list = append(cTS.list, member{}) } - - cTS.list = append(cTS.list, member{}) + // When the number of members exceeds capacity, drop the "right-most". copy(cTS.list[1:], cTS.list) cTS.list[0] = m diff --git a/trace/tracestate_test.go b/trace/tracestate_test.go index a1ef14f6f7b..784c1589219 100644 --- a/trace/tracestate_test.go +++ b/trace/tracestate_test.go @@ -482,14 +482,20 @@ func TestTraceStateInsert(t *testing.T) { err: errInvalidKey, }, { - name: "too many entries", + name: "drop the right-most member(oldest) in queue", tracestate: maxMembers, key: "keyx", value: "valx", - expected: maxMembers, - err: errMemberNumber, - }, - } + expected: func() TraceState { + // Prepend the new element and remove the oldest one, which is over capacity. + return TraceState{ + list: append( + []member{{Key: "keyx", Value: "valx"}}, + maxMembers.list[:len(maxMembers.list)-1]..., + ), + } + }(), + }} for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) {