-
Notifications
You must be signed in to change notification settings - Fork 197
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
tracestate: Allow duplicate keys but rewrite them #1183
tracestate: Allow duplicate keys but rewrite them #1183
Conversation
Changes the validation logic to allow duplicate keys to be present in tracestate entries, modifying the `NewTraceState` constructor to rewrite the duplicate keys according to the new W3C spec. Signed-off-by: Marc Lopez Rubio <[email protected]>
💚 Build Succeeded
Expand to view the summary
Build stats
Test stats 🧪
🤖 GitHub commentsTo re-run your PR in the CI, just comment with:
|
tracecontext.go
Outdated
var last *TraceStateEntry | ||
var modified []TraceStateEntry | ||
recorded := make(map[string]uint8) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could also be named seen
or observed
, I think it works either way but I'm happy to rename it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesn't make a big difference to me, happy with whichever color you choose for the bikeshed :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
couple small comments, but nothing that requires a re-review
tracecontext.go
Outdated
var last *TraceStateEntry | ||
var modified []TraceStateEntry | ||
recorded := make(map[string]uint8) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesn't make a big difference to me, happy with whichever color you choose for the bikeshed :)
tracecontext.go
Outdated
} | ||
// After we've ranged over the whole entry slice, any duplicates present | ||
// must be written first in a last to first order, thus we range the slice | ||
// backwards. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah hah, the order is why modified
is a slice and not a map?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
exactly!
tracecontext.go
Outdated
if count > 1 { | ||
for i, m := range modified { | ||
if m.Key == e.Key { | ||
modified[i] = e |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once we've found a matching key, we could continue
, right? Since we're only wanting to record the latest entry e
for a specific key e.Key
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah we could if we kept the implementation as is, I'm going to simplify it and change it to only act on the 'es' vendor key which is the only one we care about, it'll also eliminate allocations :)
tracecontext.go
Outdated
recorded[e.Key]++ | ||
} | ||
// After we've ranged over the whole entry slice, any duplicates present | ||
// must be written first in a last to first order, thus we range the slice |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: must be written in a last to first order
, I think it makes the comment a bit simpler since we're already saying last
and first
Signed-off-by: Marc Lopez Rubio <[email protected]>
tracecontext.go
Outdated
var last *TraceStateEntry | ||
var recorded uint8 | ||
// Range over the entries and find duplicate `es` vendor keys. When 'es' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm finding this method quite difficult to follow now. Would this alternative work?
var haveElastic bool
var last *TraceState
for _, e := range entries {
if e.Key == elasticTracestateVendorKey {
if haveElastic {
// Discard duplicate "es" entries; keep the last entry's value.
out.head.value = e.value
continue
}
haveElastic = true
e.next = last
last = nil // cause elastic to be moved to head
}
e := e // copy
if last == nil {
out.head = &e
} else {
last.next = &e
}
last = &e
}
if haveElastic {
out.parseElasticTracestateError = out.parseElasticTracestate(out.head)
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW we didn't previously move the elastic entry to the head because IIANM that's only expected when mutating tracestate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mostly kept the suggestion intact, but had to make some changes in 9270b6a to not lose any entries that were found previous to the es
key.
Signed-off-by: Marc Lopez Rubio <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for the updates!
Signed-off-by: Marc Lopez Rubio <[email protected]>
Changes the validation logic to allow duplicate keys to be present in tracestate entries, modifying the `NewTraceState` constructor to rewrite the duplicate `es` keys according to the new W3C spec, but leaving 3rd party duplicates untouched. Signed-off-by: Marc Lopez Rubio <[email protected]>
* CI: use apm-integration-testing/7.x for v1 Use apm-integration-testing 7.x branch for testing apm-agent-go v1. We'll update apm-integration-testing's main branch to test v2. * deps: Pin `olivere/elastic` dependency (#1178) To version `v7.0.29` for pre module Go versions. Signed-off-by: Marc Lopez Rubio <[email protected]> * tracestate: Allow duplicate keys but rewrite them (#1183) Changes the validation logic to allow duplicate keys to be present in tracestate entries, modifying the `NewTraceState` constructor to rewrite the duplicate `es` keys according to the new W3C spec, but leaving 3rd party duplicates untouched. Signed-off-by: Marc Lopez Rubio <[email protected]> Co-authored-by: Marc Lopez Rubio <[email protected]>
Verified using go.elastic.co/apm/v2 v2.0.0-20220209134054-640a916049c9 (current main), along with apmhttp/v2. To get apmhttp/v2 to work, I had to add a replace stanza:
I compared the v2 behaviour against the latest v1 agent.
|
Description
Changes the validation logic to allow duplicate keys to be present in
tracestate entries, modifying the
NewTraceState
constructor to rewritethe duplicate
es
keys according to the new W3C spec, but leaving 3rdparty duplicates untouched.
https://w3c.github.io/trace-context/#combined-header-value
Related issues
Closes #1182