Don't poll discovery service if we've received an update from the agent recently#7979
Don't poll discovery service if we've received an update from the agent recently#7979andrewlock merged 6 commits intomasterfrom
Conversation
7f41b60 to
80d155a
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
tracer/test/Datadog.Trace.TestHelpers/TransportHelpers/TestApiResponse.cs
Outdated
Show resolved
Hide resolved
This comment has been minimized.
This comment has been minimized.
Execution-Time Benchmarks Report ⏱️Execution-time results for samples comparing This PR (7979) and master. ✅ No regressions detected - check the details below Full Metrics ComparisonFakeDbCommand
HttpMessageHandler
Comparison explanationExecution-time benchmarks measure the whole time it takes to execute a program, and are intended to measure the one-off costs. Cases where the execution time results for the PR are worse than latest master results are highlighted in **red**. The following thresholds were used for comparing the execution times:
Note that these results are based on a single point-in-time result for each branch. For full results, see the dashboard. Graphs show the p99 interval based on the mean and StdDev of the test run, as well as the mean value of the run (shown as a diamond below the graph). Duration chartsFakeDbCommand (.NET Framework 4.8)gantt
title Execution time (ms) FakeDbCommand (.NET Framework 4.8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (7979) - mean (69ms) : 67, 70
master - mean (69ms) : 67, 70
section Bailout
This PR (7979) - mean (72ms) : 71, 74
master - mean (72ms) : 71, 73
section CallTarget+Inlining+NGEN
This PR (7979) - mean (1,024ms) : 943, 1104
master - mean (1,018ms) : 964, 1073
FakeDbCommand (.NET Core 3.1)gantt
title Execution time (ms) FakeDbCommand (.NET Core 3.1)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (7979) - mean (106ms) : 103, 110
master - mean (107ms) : 104, 109
section Bailout
This PR (7979) - mean (107ms) : 106, 108
master - mean (108ms) : 106, 110
section CallTarget+Inlining+NGEN
This PR (7979) - mean (739ms) : 691, 787
master - mean (746ms) : 672, 820
FakeDbCommand (.NET 6)gantt
title Execution time (ms) FakeDbCommand (.NET 6)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (7979) - mean (94ms) : 92, 96
master - mean (95ms) : 92, 98
section Bailout
This PR (7979) - mean (94ms) : 93, 95
master - mean (97ms) : 89, 104
section CallTarget+Inlining+NGEN
This PR (7979) - mean (716ms) : 678, 753
master - mean (714ms) : 665, 762
FakeDbCommand (.NET 8)gantt
title Execution time (ms) FakeDbCommand (.NET 8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (7979) - mean (92ms) : 90, 95
master - mean (94ms) : 90, 97
section Bailout
This PR (7979) - mean (94ms) : 92, 95
master - mean (95ms) : 93, 97
section CallTarget+Inlining+NGEN
This PR (7979) - mean (634ms) : 619, 650
master - mean (638ms) : 615, 662
HttpMessageHandler (.NET Framework 4.8)gantt
title Execution time (ms) HttpMessageHandler (.NET Framework 4.8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (7979) - mean (192ms) : 187, 196
master - mean (192ms) : 188, 196
section Bailout
This PR (7979) - mean (196ms) : 193, 198
master - mean (195ms) : 192, 198
section CallTarget+Inlining+NGEN
This PR (7979) - mean (1,115ms) : 1053, 1177
master - mean (1,122ms) : 1059, 1186
HttpMessageHandler (.NET Core 3.1)gantt
title Execution time (ms) HttpMessageHandler (.NET Core 3.1)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (7979) - mean (275ms) : 270, 280
master - mean (275ms) : 269, 280
section Bailout
This PR (7979) - mean (276ms) : 271, 281
master - mean (276ms) : 272, 280
section CallTarget+Inlining+NGEN
This PR (7979) - mean (931ms) : 895, 967
master - mean (925ms) : 873, 978
HttpMessageHandler (.NET 6)gantt
title Execution time (ms) HttpMessageHandler (.NET 6)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (7979) - mean (268ms) : 262, 275
master - mean (268ms) : 264, 273
section Bailout
This PR (7979) - mean (269ms) : 265, 273
master - mean (268ms) : 264, 272
section CallTarget+Inlining+NGEN
This PR (7979) - mean (924ms) : 886, 963
master - mean (927ms) : 890, 965
HttpMessageHandler (.NET 8)gantt
title Execution time (ms) HttpMessageHandler (.NET 8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (7979) - mean (268ms) : 263, 273
master - mean (267ms) : 262, 272
section Bailout
This PR (7979) - mean (268ms) : 264, 273
master - mean (267ms) : 264, 271
section CallTarget+Inlining+NGEN
This PR (7979) - mean (830ms) : 812, 847
master - mean (819ms) : 797, 841
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
BenchmarksBenchmark execution time: 2026-01-12 16:20:55 Comparing candidate commit f562bd6 in PR branch Found 5 performance improvements and 9 performance regressions! Performance is the same for 159 metrics, 13 unstable metrics. scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.AllCycleSimpleBody netcoreapp3.1
scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.ObjectExtractorMoreComplexBody net6.0
scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.ObjectExtractorSimpleBody netcoreapp3.1
scenario:Benchmarks.Trace.Asm.AppSecEncoderBenchmark.EncodeLegacyArgs netcoreapp3.1
scenario:Benchmarks.Trace.Asm.AppSecWafBenchmark.RunWafRealisticBenchmarkWithAttack netcoreapp3.1
scenario:Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces net472
scenario:Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces netcoreapp3.1
scenario:Benchmarks.Trace.CharSliceBenchmark.OriginalCharSlice net6.0
scenario:Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark net6.0
scenario:Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatBenchmark net6.0
scenario:Benchmarks.Trace.Log4netBenchmark.EnrichedLog netcoreapp3.1
scenario:Benchmarks.Trace.NLogBenchmark.EnrichedLog net6.0
scenario:Benchmarks.Trace.SpanBenchmark.StartFinishScope net6.0
|
46bf894 to
e985c05
Compare
| } | ||
|
|
||
| [TestingAndPrivateOnly] | ||
| internal bool RequireRefresh(string? currentHash, DateTimeOffset utcNow) |
There was a problem hiding this comment.
Could there be a race condition here?
Thread A reads _agentConfigStateHash
Thread B calls SetCurrentConfigStateHash() and updates hash and time
Thread A reads _agentConfigStateHashUnixTime and gets a fresh timestamp, return false
Not critical though, it would be rare and the consecuences are not severe. WDYT?
There was a problem hiding this comment.
Could there be a race condition here?
Yup, absolutely, there could. When I first wrote this, I worked around that by creating a record State(string Hash, DateTimeOffset utcNow) and then atomically switching that. The problem is that SetCurrentConfigStateHash() is going to be called a lot, so it would result in either a more complex "atomically read, compare, conditionally recreate , atomically write" comparison, or if we just always write (like we're doing currently) then we end up allocating every time.
My conclusion was pretty much the same as yours, it should be rare, and not severe (we will pick it up next time), and given this is primarily meant to be a perf improvement, I think it's worth it 🙂
e985c05 to
c50e32e
Compare
…it's deserialized
c50e32e to
f562bd6
Compare
Summary of changes
Don't poll discovery service if we're received an update from the agent recently
Reason for change
The agent sends a sha256 hash of the
/infoendpoint data in every response. We can use that to track whether the/infovalue has changed, and if it hasn't, we can skip polling the endpoint needlessly.This obviously removes the overhead of polling the endpoint, but it's not entirely clear the impact this will have on performance, as we're doing "extra" work by materializing the header and calling the discovery service, everytime we send a trace.
Implementation details
/infodata, take a SHA256 of the data, and store it as a hex stringDiscoveryServiceDiscoveryServiceis next due to poll (every 30s) check if the existing hash matches the most recent value from the header (and that it was received within the last 30s). If so, skip the current poll.Test coverage
Added unit tests for all of the components
Other details
https://datadoghq.atlassian.net/browse/LANGPLAT-815
Couple of points of interest:
CryptoStreammakes calculating the hash low allocation, but it assumes we're receiving the data as UTF-8 etc (which we are, but you know, we don't currently verify that)