-
Notifications
You must be signed in to change notification settings - Fork 150
cleaning pass on HotChocolate instrumentation #6580
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
Conversation
// Get the string value of the NameString | ||
// The NameString value can be either another NameString or a string |
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.
the property is defined here: https://github.com/ChilliCream/graphql-platform/blob/c162ca29c23acc69cf81a33155d7384ad4dc9d0f/src/HotChocolate/Core/src/Types/Resolvers/IOperation.cs#L30
It's a struct that looks like a nullable (it has HasValue
and Value
properties), which is itself a nullable, so there is 2 levels of .Value
to get, which explains the initial confusion around this I think.
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 somewhat intrigued and afraid by this, and I'm wondering if we actually have any tests that hit the behaviour 🤔 my concern is because nullable types are really weird 😅 I suspect it is fine in this case, just would be more comfortable if we new we were covering all these paths:
NameValue is null
NameValue.Value is null
NameValue.Value is not null
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.
In fact, I'm almost certain this isn't covered, because the behaviour has changed significantly here 🤔
Before, we always created an operation, and then updated the details of the current span. Now you don't do that at all if the operation name is null... That seems like a potentially breaking change?
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.
how can the .Value
be null when they are actual non-nullable struct ?
This is not the latest code that we are commenting on too, it now looks like operation.Name.HasValue ? operation.Name.Value.Value : null
operation
is not null/default because we check HasValue
before, so here we check name, and then name.Value, any of those can be null.
In any case, we do update the span even if one of those values is null.
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.
Are we talking about this NameString
?
If so, this is a custom struct
, not a Nullable<T>
. And this property is a Nullable<NameString>
.
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.
Just trying to understand the issue :)
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.
Yes that's right, it's a nullable of a custom struct, but we need a proxy both for the nullable and the NameString struct
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.
Before, we always created an operation, and then updated the details of the current span. Now you don't do that at all if the operation name is null
Yeah, ignore this, got my operation vs operation name's confused 😅
I also got confused by the fact there's actually three layers of potential null, IOperationContext.Operation
could be null (which is the extra guard you added), and then Operation.NameValue could be null, and Operation.NameValue.Value could be null 😅
...er/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/GraphQL/HotChocolate/IOperationProxy.cs
Outdated
Show resolved
Hide resolved
Datadog ReportBranch report: ❌ 192 Failed (0 Known Flaky), 541878 Passed, 3557 Skipped, 29h 47m 13.94s Total Time ❌ Failed Tests (192)
|
Execution-Time Benchmarks Report ⏱️Execution-time results for samples comparing the following branches/commits: Execution-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 shown 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). gantt
title Execution time (ms) FakeDbCommand (.NET Framework 4.6.2)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6580) - mean (69ms) : 67, 72
. : milestone, 69,
master - mean (69ms) : 66, 72
. : milestone, 69,
section CallTarget+Inlining+NGEN
This PR (6580) - mean (993ms) : 970, 1015
. : milestone, 993,
master - mean (990ms) : 968, 1011
. : milestone, 990,
gantt
title Execution time (ms) FakeDbCommand (.NET Core 3.1)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6580) - mean (103ms) : 101, 105
. : milestone, 103,
master - mean (103ms) : 100, 105
. : milestone, 103,
section CallTarget+Inlining+NGEN
This PR (6580) - mean (673ms) : 656, 689
. : milestone, 673,
master - mean (674ms) : 660, 688
. : milestone, 674,
gantt
title Execution time (ms) FakeDbCommand (.NET 6)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6580) - mean (90ms) : 88, 92
. : milestone, 90,
master - mean (89ms) : 88, 91
. : milestone, 89,
section CallTarget+Inlining+NGEN
This PR (6580) - mean (624ms) : 610, 638
. : milestone, 624,
master - mean (630ms) : 616, 644
. : milestone, 630,
gantt
title Execution time (ms) HttpMessageHandler (.NET Framework 4.6.2)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6580) - mean (190ms) : 186, 194
. : milestone, 190,
master - mean (190ms) : 185, 194
. : milestone, 190,
section CallTarget+Inlining+NGEN
This PR (6580) - mean (1,099ms) : 1065, 1133
. : milestone, 1099,
master - mean (1,097ms) : 1069, 1125
. : milestone, 1097,
gantt
title Execution time (ms) HttpMessageHandler (.NET Core 3.1)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6580) - mean (269ms) : 265, 273
. : milestone, 269,
master - mean (271ms) : 263, 278
. : milestone, 271,
section CallTarget+Inlining+NGEN
This PR (6580) - mean (860ms) : 821, 900
. : milestone, 860,
master - mean (860ms) : 831, 889
. : milestone, 860,
gantt
title Execution time (ms) HttpMessageHandler (.NET 6)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6580) - mean (261ms) : 258, 265
. : milestone, 261,
master - mean (261ms) : 257, 265
. : milestone, 261,
section CallTarget+Inlining+NGEN
This PR (6580) - mean (840ms) : 807, 872
. : milestone, 840,
master - mean (844ms) : 808, 880
. : milestone, 844,
|
...src/Datadog.Trace/ClrProfiler/AutoInstrumentation/GraphQL/HotChocolate/IOperationProxyV13.cs
Outdated
Show resolved
Hide resolved
Benchmarks Report for tracer 🐌Benchmarks for #6580 compared to master:
The following thresholds were used for comparing the benchmark speeds:
Allocation changes below 0.5% are ignored. Benchmark detailsBenchmarks.Trace.ActivityBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.AgentWriterBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.AspNetCoreBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark - Same speed ✔️ More allocations
|
Benchmark | Base Allocated | Diff Allocated | Change | Change % |
---|---|---|---|---|
Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces‑netcoreapp3.1 | 41.53 KB | 41.76 KB | 229 B | 0.55% |
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | WriteAndFlushEnrichedTraces |
net6.0 | 579μs | 3.18μs | 18.3μs | 0.551 | 0 | 0 | 41.68 KB |
master | WriteAndFlushEnrichedTraces |
netcoreapp3.1 | 690μs | 3.73μs | 19.7μs | 0.338 | 0 | 0 | 41.53 KB |
master | WriteAndFlushEnrichedTraces |
net472 | 839μs | 3.07μs | 11.1μs | 8.39 | 2.52 | 0.419 | 53.3 KB |
#6580 | WriteAndFlushEnrichedTraces |
net6.0 | 548μs | 2.88μs | 13.8μs | 0.541 | 0 | 0 | 41.54 KB |
#6580 | WriteAndFlushEnrichedTraces |
netcoreapp3.1 | 641μs | 2.77μs | 9.99μs | 0.324 | 0 | 0 | 41.76 KB |
#6580 | WriteAndFlushEnrichedTraces |
net472 | 847μs | 2.96μs | 11.5μs | 8.08 | 2.55 | 0.425 | 53.31 KB |
Benchmarks.Trace.DbCommandBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | ExecuteNonQuery |
net6.0 | 1.3μs | 1.05ns | 4.07ns | 0.0143 | 0 | 0 | 1.02 KB |
master | ExecuteNonQuery |
netcoreapp3.1 | 1.81μs | 1.46ns | 5.66ns | 0.0136 | 0 | 0 | 1.02 KB |
master | ExecuteNonQuery |
net472 | 2.13μs | 2.74ns | 10.6ns | 0.157 | 0.00107 | 0 | 987 B |
#6580 | ExecuteNonQuery |
net6.0 | 1.22μs | 0.861ns | 3.1ns | 0.0143 | 0 | 0 | 1.02 KB |
#6580 | ExecuteNonQuery |
netcoreapp3.1 | 1.75μs | 1.97ns | 7.64ns | 0.0138 | 0 | 0 | 1.02 KB |
#6580 | ExecuteNonQuery |
net472 | 1.98μs | 1.81ns | 7.01ns | 0.156 | 0.000995 | 0 | 987 B |
Benchmarks.Trace.ElasticsearchBenchmark - Slower ⚠️ Same allocations ✔️
Slower ⚠️ in #6580
Benchmark
diff/base
Base Median (ns)
Diff Median (ns)
Modality
Benchmarks.Trace.ElasticsearchBenchmark.CallElasticsearchAsync‑net6.0
1.120
1,293.97
1,449.52
Benchmark | diff/base | Base Median (ns) | Diff Median (ns) | Modality |
---|---|---|---|---|
Benchmarks.Trace.ElasticsearchBenchmark.CallElasticsearchAsync‑net6.0 | 1.120 | 1,293.97 | 1,449.52 |
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | CallElasticsearch |
net6.0 | 1.2μs | 0.618ns | 2.39ns | 0.0139 | 0 | 0 | 976 B |
master | CallElasticsearch |
netcoreapp3.1 | 1.58μs | 0.823ns | 3.19ns | 0.0134 | 0 | 0 | 976 B |
master | CallElasticsearch |
net472 | 2.59μs | 2.1ns | 8.15ns | 0.158 | 0 | 0 | 995 B |
master | CallElasticsearchAsync |
net6.0 | 1.29μs | 0.474ns | 1.84ns | 0.0137 | 0 | 0 | 952 B |
master | CallElasticsearchAsync |
netcoreapp3.1 | 1.66μs | 1.26ns | 4.86ns | 0.0141 | 0 | 0 | 1.02 KB |
master | CallElasticsearchAsync |
net472 | 2.72μs | 1.29ns | 4.98ns | 0.166 | 0 | 0 | 1.05 KB |
#6580 | CallElasticsearch |
net6.0 | 1.3μs | 0.832ns | 3.22ns | 0.0136 | 0 | 0 | 976 B |
#6580 | CallElasticsearch |
netcoreapp3.1 | 1.49μs | 0.804ns | 3.01ns | 0.0127 | 0 | 0 | 976 B |
#6580 | CallElasticsearch |
net472 | 2.51μs | 1.32ns | 4.94ns | 0.157 | 0 | 0 | 995 B |
#6580 | CallElasticsearchAsync |
net6.0 | 1.45μs | 1.04ns | 3.91ns | 0.0131 | 0 | 0 | 952 B |
#6580 | CallElasticsearchAsync |
netcoreapp3.1 | 1.6μs | 0.75ns | 2.8ns | 0.0139 | 0 | 0 | 1.02 KB |
#6580 | CallElasticsearchAsync |
net472 | 2.69μs | 1.65ns | 6.4ns | 0.167 | 0 | 0 | 1.05 KB |
Benchmarks.Trace.GraphQLBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | ExecuteAsync |
net6.0 | 1.34μs | 0.698ns | 2.52ns | 0.0134 | 0 | 0 | 952 B |
master | ExecuteAsync |
netcoreapp3.1 | 1.58μs | 1.47ns | 5.71ns | 0.0126 | 0 | 0 | 952 B |
master | ExecuteAsync |
net472 | 1.84μs | 0.551ns | 2.06ns | 0.145 | 0 | 0 | 915 B |
#6580 | ExecuteAsync |
net6.0 | 1.27μs | 0.331ns | 1.2ns | 0.0134 | 0 | 0 | 952 B |
#6580 | ExecuteAsync |
netcoreapp3.1 | 1.58μs | 1.02ns | 3.81ns | 0.0128 | 0 | 0 | 952 B |
#6580 | ExecuteAsync |
net472 | 1.85μs | 0.497ns | 1.92ns | 0.145 | 0 | 0 | 915 B |
Benchmarks.Trace.HttpClientBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | SendAsync |
net6.0 | 4.41μs | 1.63ns | 6.09ns | 0.0308 | 0 | 0 | 2.31 KB |
master | SendAsync |
netcoreapp3.1 | 5.43μs | 3.36ns | 13ns | 0.0381 | 0 | 0 | 2.85 KB |
master | SendAsync |
net472 | 7.39μs | 2.95ns | 11.4ns | 0.493 | 0 | 0 | 3.12 KB |
#6580 | SendAsync |
net6.0 | 4.19μs | 1.56ns | 5.83ns | 0.0313 | 0 | 0 | 2.31 KB |
#6580 | SendAsync |
netcoreapp3.1 | 5.3μs | 4.07ns | 14.7ns | 0.0372 | 0 | 0 | 2.85 KB |
#6580 | SendAsync |
net472 | 7.44μs | 2.53ns | 9.48ns | 0.495 | 0 | 0 | 3.12 KB |
Benchmarks.Trace.ILoggerBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | EnrichedLog |
net6.0 | 1.45μs | 0.751ns | 2.81ns | 0.0233 | 0 | 0 | 1.64 KB |
master | EnrichedLog |
netcoreapp3.1 | 2.14μs | 1.07ns | 3.85ns | 0.0224 | 0 | 0 | 1.64 KB |
master | EnrichedLog |
net472 | 2.43μs | 0.734ns | 2.75ns | 0.249 | 0 | 0 | 1.57 KB |
#6580 | EnrichedLog |
net6.0 | 1.49μs | 0.903ns | 3.38ns | 0.0231 | 0 | 0 | 1.64 KB |
#6580 | EnrichedLog |
netcoreapp3.1 | 2.28μs | 1.55ns | 5.99ns | 0.0228 | 0 | 0 | 1.64 KB |
#6580 | EnrichedLog |
net472 | 2.63μs | 1.12ns | 4.18ns | 0.249 | 0 | 0 | 1.57 KB |
Benchmarks.Trace.Log4netBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | EnrichedLog |
net6.0 | 113μs | 90.1ns | 325ns | 0.0566 | 0 | 0 | 4.28 KB |
master | EnrichedLog |
netcoreapp3.1 | 116μs | 194ns | 753ns | 0.058 | 0 | 0 | 4.28 KB |
master | EnrichedLog |
net472 | 151μs | 140ns | 541ns | 0.678 | 0.226 | 0 | 4.46 KB |
#6580 | EnrichedLog |
net6.0 | 113μs | 74.2ns | 267ns | 0.0561 | 0 | 0 | 4.28 KB |
#6580 | EnrichedLog |
netcoreapp3.1 | 116μs | 129ns | 499ns | 0.0572 | 0 | 0 | 4.28 KB |
#6580 | EnrichedLog |
net472 | 150μs | 131ns | 507ns | 0.674 | 0.225 | 0 | 4.46 KB |
Benchmarks.Trace.NLogBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | EnrichedLog |
net6.0 | 3.04μs | 1.23ns | 4.58ns | 0.0304 | 0 | 0 | 2.2 KB |
master | EnrichedLog |
netcoreapp3.1 | 4.1μs | 1.25ns | 4.83ns | 0.0287 | 0 | 0 | 2.2 KB |
master | EnrichedLog |
net472 | 4.88μs | 1.66ns | 6.42ns | 0.319 | 0 | 0 | 2.02 KB |
#6580 | EnrichedLog |
net6.0 | 3.03μs | 1.32ns | 5.13ns | 0.0304 | 0 | 0 | 2.2 KB |
#6580 | EnrichedLog |
netcoreapp3.1 | 4.16μs | 1.17ns | 4.53ns | 0.0289 | 0 | 0 | 2.2 KB |
#6580 | EnrichedLog |
net472 | 4.92μs | 0.803ns | 3ns | 0.32 | 0 | 0 | 2.02 KB |
Benchmarks.Trace.RedisBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | SendReceive |
net6.0 | 1.31μs | 0.891ns | 3.45ns | 0.0157 | 0 | 0 | 1.14 KB |
master | SendReceive |
netcoreapp3.1 | 1.82μs | 1.13ns | 4.39ns | 0.0155 | 0 | 0 | 1.14 KB |
master | SendReceive |
net472 | 2.06μs | 0.688ns | 2.66ns | 0.183 | 0 | 0 | 1.16 KB |
#6580 | SendReceive |
net6.0 | 1.36μs | 1.2ns | 4.66ns | 0.0157 | 0 | 0 | 1.14 KB |
#6580 | SendReceive |
netcoreapp3.1 | 1.81μs | 0.825ns | 3.19ns | 0.0154 | 0 | 0 | 1.14 KB |
#6580 | SendReceive |
net472 | 2.06μs | 0.469ns | 1.81ns | 0.183 | 0 | 0 | 1.16 KB |
Benchmarks.Trace.SerilogBenchmark - Faster 🎉 Same allocations ✔️
Faster 🎉 in #6580
Benchmark
base/diff
Base Median (ns)
Diff Median (ns)
Modality
Benchmarks.Trace.SerilogBenchmark.EnrichedLog‑net6.0
1.125
2,966.24
2,635.64
Benchmark | base/diff | Base Median (ns) | Diff Median (ns) | Modality |
---|---|---|---|---|
Benchmarks.Trace.SerilogBenchmark.EnrichedLog‑net6.0 | 1.125 | 2,966.24 | 2,635.64 |
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | EnrichedLog |
net6.0 | 2.97μs | 0.753ns | 2.92ns | 0.0222 | 0 | 0 | 1.6 KB |
master | EnrichedLog |
netcoreapp3.1 | 3.84μs | 2.18ns | 8.42ns | 0.0211 | 0 | 0 | 1.65 KB |
master | EnrichedLog |
net472 | 4.41μs | 2.44ns | 9.11ns | 0.323 | 0 | 0 | 2.04 KB |
#6580 | EnrichedLog |
net6.0 | 2.64μs | 1.56ns | 6.03ns | 0.0225 | 0 | 0 | 1.6 KB |
#6580 | EnrichedLog |
netcoreapp3.1 | 3.98μs | 1.12ns | 4.2ns | 0.0219 | 0 | 0 | 1.65 KB |
#6580 | EnrichedLog |
net472 | 4.5μs | 1.75ns | 6.8ns | 0.323 | 0 | 0 | 2.04 KB |
Benchmarks.Trace.SpanBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | StartFinishSpan |
net6.0 | 420ns | 0.632ns | 2.45ns | 0.00804 | 0 | 0 | 576 B |
master | StartFinishSpan |
netcoreapp3.1 | 561ns | 0.825ns | 3.2ns | 0.0078 | 0 | 0 | 576 B |
master | StartFinishSpan |
net472 | 575ns | 1.49ns | 5.78ns | 0.0916 | 0 | 0 | 578 B |
master | StartFinishScope |
net6.0 | 539ns | 0.976ns | 3.78ns | 0.00964 | 0 | 0 | 696 B |
master | StartFinishScope |
netcoreapp3.1 | 804ns | 1.28ns | 4.95ns | 0.00964 | 0 | 0 | 696 B |
master | StartFinishScope |
net472 | 871ns | 2.4ns | 9.29ns | 0.104 | 0 | 0 | 658 B |
#6580 | StartFinishSpan |
net6.0 | 414ns | 0.662ns | 2.56ns | 0.00817 | 0 | 0 | 576 B |
#6580 | StartFinishSpan |
netcoreapp3.1 | 556ns | 0.998ns | 3.86ns | 0.00782 | 0 | 0 | 576 B |
#6580 | StartFinishSpan |
net472 | 599ns | 1.27ns | 4.59ns | 0.0915 | 0 | 0 | 578 B |
#6580 | StartFinishScope |
net6.0 | 540ns | 1.17ns | 4.54ns | 0.00978 | 0 | 0 | 696 B |
#6580 | StartFinishScope |
netcoreapp3.1 | 779ns | 1.03ns | 3.97ns | 0.00934 | 0 | 0 | 696 B |
#6580 | StartFinishScope |
net472 | 829ns | 1.39ns | 5.4ns | 0.105 | 0 | 0 | 658 B |
Benchmarks.Trace.TraceAnnotationsBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | RunOnMethodBegin |
net6.0 | 660ns | 0.696ns | 2.69ns | 0.00991 | 0 | 0 | 696 B |
master | RunOnMethodBegin |
netcoreapp3.1 | 933ns | 2.35ns | 9.1ns | 0.00918 | 0 | 0 | 696 B |
master | RunOnMethodBegin |
net472 | 1.03μs | 1.58ns | 6.1ns | 0.104 | 0 | 0 | 658 B |
#6580 | RunOnMethodBegin |
net6.0 | 598ns | 0.823ns | 3.19ns | 0.00982 | 0 | 0 | 696 B |
#6580 | RunOnMethodBegin |
netcoreapp3.1 | 879ns | 1.3ns | 5.05ns | 0.00918 | 0 | 0 | 696 B |
#6580 | RunOnMethodBegin |
net472 | 1.06μs | 1.56ns | 6.05ns | 0.104 | 0 | 0 | 658 B |
Datadog ReportBranch report: ✅ 0 Failed, 552168 Passed, 4428 Skipped, 32h 20m 12.73s Total Time |
// Get the string value of the NameString | ||
// The NameString value can be either another NameString or a string |
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 somewhat intrigued and afraid by this, and I'm wondering if we actually have any tests that hit the behaviour 🤔 my concern is because nullable types are really weird 😅 I suspect it is fine in this case, just would be more comfortable if we new we were covering all these paths:
NameValue is null
NameValue.Value is null
NameValue.Value is not null
// Get the string value of the NameString | ||
// The NameString value can be either another NameString or a string |
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.
In fact, I'm almost certain this isn't covered, because the behaviour has changed significantly here 🤔
Before, we always created an operation, and then updated the details of the current span. Now you don't do that at all if the operation name is null... That seems like a potentially breaking change?
...race/ClrProfiler/AutoInstrumentation/GraphQL/HotChocolate/ExecuteAsyncIntegrationExtraV13.cs
Show resolved
Hide resolved
tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/GraphQL/HotChocolate/IQueryRequest.cs
Show resolved
Hide resolved
/// <summary> | ||
/// nullable structs need an explicit proxy | ||
/// </summary> |
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 one still blows my mind, I'd love to see some tests for 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.
I mean there are tests on ducktype here but you mean tests for this specific one ?
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 really mean as part of the integration test, cases where NameString
is null, and/or where NameString.Value
is null
. I don't know if that's practical, just changing duck types always makes me a bit nervous 😄
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 added a test where the nullable is null (I don't know how to make the NameString have no value though)
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.
Hmmm, there's no associated span in the new snapshots though are there? 🤔
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.
The comment shows aspnetcore spans, but I don't see any hotchocolate/graphql spans - we'd expect to see one of those wouldn't we? 🤔
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, right. I'll double check what is happening
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 you were right to be suspicious, because it doesn't do what I think it would ^^
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.
ok, it turns out that this query:
dd-trace-dotnet/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/HotChocolateTests.cs
Line 126 in 108670c
SubmitGraphqlRequest(url: "/graphql?query=" + WebUtility.UrlEncode("query{book{title author{name}}}"), httpMethod: "GET", graphQlRequestBody: null); |
has a null operation name (this is what I was seeing with my breakpoint and I didn't double check). We can see that it has an operation type:
Line 43 in 108670c
graphql.operation.type: Query, |
but the operation name field is not filled for that one.
But don't ask me why that is !
I'll remove my extra test case, which was discarded before it reaches the GraphQL execute
method, probably by the parser I'd say.
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.
Ok cool, so we do already have tests for this, cool, thanks! 🙂
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 this and for all the follow up!
## Summary of changes Follow up on #6248 Some cracks in the nullable analysis were pointed by Andrew, I wanted to fix those, and I also noticed that there were a couple weird things that could be ironed out too. ## Reason for change ## Implementation details - add some checks on things that can be null - remove weird code around NameType ## Test coverage ## Other details <!-- Fixes #{issue} --> <!--⚠️ Note: where possible, please obtain 2 approvals prior to merging. Unless CODEOWNERS specifies otherwise, for external teams it is typically best to have one review from a team member, and one review from apm-dotnet. Trivial changes do not require 2 reviews. -->
Summary of changes
Follow up on #6248
Some cracks in the nullable analysis were pointed by Andrew, I wanted to fix those, and I also noticed that there were a couple weird things that could be ironed out too.
Reason for change
Implementation details
Test coverage
Other details