Skip to content

Commit 0d61918

Browse files
committed
PR feedback
1 parent 2108cd3 commit 0d61918

File tree

2 files changed

+93
-20
lines changed

2 files changed

+93
-20
lines changed

src/Shared/Diagnostics/ActivityCreator.cs

+23-7
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,18 @@ internal static class ActivityCreator
2020
IEnumerable<ActivityLink>? links,
2121
bool diagnosticsOrLoggingEnabled)
2222
{
23-
propagator.ExtractTraceIdAndState(
24-
distributedContextCarrier,
25-
propagatorGetter,
26-
out var requestId,
27-
out var traceState);
28-
2923
Activity? activity = null;
24+
string? requestId = null;
25+
string? traceState = null;
26+
3027
if (activitySource.HasListeners())
3128
{
29+
propagator.ExtractTraceIdAndState(
30+
distributedContextCarrier,
31+
propagatorGetter,
32+
out requestId,
33+
out traceState);
34+
3235
if (ActivityContext.TryParse(requestId, traceState, isRemote: true, out ActivityContext context))
3336
{
3437
// The requestId used the W3C ID format. Unfortunately, the ActivitySource.CreateActivity overload that
@@ -40,7 +43,7 @@ internal static class ActivityCreator
4043
else
4144
{
4245
// Pass in the ID we got from the headers if there was one.
43-
activity = activitySource.CreateActivity(activityName, ActivityKind.Server, string.IsNullOrEmpty(requestId) ? null! : requestId, tags: tags, links: links);
46+
activity = activitySource.CreateActivity(activityName, ActivityKind.Server, string.IsNullOrEmpty(requestId) ? null : requestId, tags: tags, links: links);
4447
}
4548
}
4649

@@ -50,6 +53,19 @@ internal static class ActivityCreator
5053
// case when there are no listeners). Let's create it here if needed.
5154
if (diagnosticsOrLoggingEnabled)
5255
{
56+
// Note that there is a very small chance that propagator has already been called.
57+
// Requires that the activity source had listened, but it didn't create an activity.
58+
// Can only happen if there is a race between HasListeners and CreateActivity calls,
59+
// and someone removing the listener.
60+
//
61+
// The only negative of calling the propagator twice is a small performance hit, but
62+
// it's small and unlikely so it's not worth trying to optimize.
63+
propagator.ExtractTraceIdAndState(
64+
distributedContextCarrier,
65+
propagatorGetter,
66+
out requestId,
67+
out traceState);
68+
5369
activity = new Activity(activityName);
5470
if (!string.IsNullOrEmpty(requestId))
5571
{

src/SignalR/clients/csharp/Client/test/FunctionalTests/HubConnectionTests.cs

+70-13
Original file line numberDiff line numberDiff line change
@@ -140,16 +140,43 @@ public async Task InvokeAsync_SendTraceHeader(string protocolName, HttpTransport
140140

141141
var connection = connectionBuilder.Build();
142142

143-
using var clientActivity = new Activity("ClientActivity");
144-
clientActivity.Start();
145-
143+
Activity clientActivity1 = null;
144+
Activity clientActivity2 = null;
146145
try
147146
{
148147
await connection.StartAsync().DefaultTimeout();
149148

150-
var result = await connection.InvokeAsync<string>(nameof(TestHub.HelloWorld)).DefaultTimeout();
149+
// Invocation 1
150+
try
151+
{
152+
clientActivity1 = new Activity("ClientActivity1");
153+
clientActivity1.AddBaggage("baggage-1", "value-1");
154+
clientActivity1.Start();
151155

152-
Assert.Equal("Hello World!", result);
156+
var result = await connection.InvokeAsync<string>(nameof(TestHub.HelloWorld)).DefaultTimeout();
157+
158+
Assert.Equal("Hello World!", result);
159+
}
160+
finally
161+
{
162+
clientActivity1?.Stop();
163+
}
164+
165+
// Invocation 2
166+
try
167+
{
168+
clientActivity2 = new Activity("ClientActivity2");
169+
clientActivity2.AddBaggage("baggage-2", "value-2");
170+
clientActivity2.Start();
171+
172+
var result = await connection.InvokeAsync<string>(nameof(TestHub.HelloWorld)).DefaultTimeout();
173+
174+
Assert.Equal("Hello World!", result);
175+
}
176+
finally
177+
{
178+
clientActivity2?.Stop();
179+
}
153180
}
154181
catch (Exception ex)
155182
{
@@ -158,11 +185,10 @@ public async Task InvokeAsync_SendTraceHeader(string protocolName, HttpTransport
158185
}
159186
finally
160187
{
161-
clientActivity.Stop();
162188
await connection.DisposeAsync().DefaultTimeout();
163189
}
164190

165-
var activities = await channel.Reader.ReadAtLeastAsync(minimumCount: 3).DefaultTimeout();
191+
var activities = await channel.Reader.ReadAtLeastAsync(minimumCount: 4).DefaultTimeout();
166192

167193
var hubName = path switch
168194
{
@@ -178,18 +204,38 @@ public async Task InvokeAsync_SendTraceHeader(string protocolName, HttpTransport
178204
Assert.Equal($"{hubName}/OnConnectedAsync", a.OperationName);
179205
Assert.Equal("Microsoft.AspNetCore.Hosting.HttpRequestIn", a.Parent.OperationName);
180206
Assert.False(a.HasRemoteParent);
207+
Assert.Empty(a.Baggage);
181208
},
182209
a =>
183210
{
184211
Assert.Equal($"{hubName}/HelloWorld", a.OperationName);
212+
Assert.Equal(clientActivity1.Id, a.ParentId);
185213
Assert.True(a.HasRemoteParent);
186-
Assert.Equal(clientActivity.Id, a.ParentId);
214+
Assert.Collection(a.Baggage,
215+
b =>
216+
{
217+
Assert.Equal("baggage-1", b.Key);
218+
Assert.Equal("value-1", b.Value);
219+
});
220+
},
221+
a =>
222+
{
223+
Assert.Equal($"{hubName}/HelloWorld", a.OperationName);
224+
Assert.Equal(clientActivity2.Id, a.ParentId);
225+
Assert.True(a.HasRemoteParent);
226+
Assert.Collection(a.Baggage,
227+
b =>
228+
{
229+
Assert.Equal("baggage-2", b.Key);
230+
Assert.Equal("value-2", b.Value);
231+
});
187232
},
188233
a =>
189234
{
190235
Assert.Equal($"{hubName}/OnDisconnectedAsync", a.OperationName);
191236
Assert.Equal("Microsoft.AspNetCore.Hosting.HttpRequestIn", a.Parent.OperationName);
192237
Assert.False(a.HasRemoteParent);
238+
Assert.Empty(a.Baggage);
193239
});
194240
}
195241
}
@@ -570,12 +616,15 @@ public async Task StreamAsyncCore_SendTraceHeader(string protocolName, HttpTrans
570616

571617
var connection = CreateHubConnection(server.Url, path, transportType, protocol, LoggerFactory);
572618

573-
using var clientActivity = new Activity("ClientActivity");
574-
clientActivity.Start();
575-
619+
Activity clientActivity = null;
576620
try
577621
{
578622
await connection.StartAsync().DefaultTimeout();
623+
624+
clientActivity = new Activity("ClientActivity");
625+
clientActivity.AddBaggage("baggage-1", "value-1");
626+
clientActivity.Start();
627+
579628
var expectedValue = 0;
580629
var streamTo = 5;
581630
var asyncEnumerable = connection.StreamAsyncCore<int>("Stream", new object[] { streamTo });
@@ -594,7 +643,7 @@ public async Task StreamAsyncCore_SendTraceHeader(string protocolName, HttpTrans
594643
}
595644
finally
596645
{
597-
clientActivity.Stop();
646+
clientActivity?.Stop();
598647
await connection.DisposeAsync().DefaultTimeout();
599648
}
600649

@@ -614,18 +663,26 @@ public async Task StreamAsyncCore_SendTraceHeader(string protocolName, HttpTrans
614663
Assert.Equal($"{hubName}/OnConnectedAsync", a.OperationName);
615664
Assert.Equal("Microsoft.AspNetCore.Hosting.HttpRequestIn", a.Parent.OperationName);
616665
Assert.False(a.HasRemoteParent);
666+
Assert.Empty(a.Baggage);
617667
},
618668
a =>
619669
{
620670
Assert.Equal($"{hubName}/Stream", a.OperationName);
621-
Assert.True(a.HasRemoteParent);
622671
Assert.Equal(clientActivity.Id, a.ParentId);
672+
Assert.True(a.HasRemoteParent);
673+
Assert.Collection(a.Baggage,
674+
b =>
675+
{
676+
Assert.Equal("baggage-1", b.Key);
677+
Assert.Equal("value-1", b.Value);
678+
});
623679
},
624680
a =>
625681
{
626682
Assert.Equal($"{hubName}/OnDisconnectedAsync", a.OperationName);
627683
Assert.Equal("Microsoft.AspNetCore.Hosting.HttpRequestIn", a.Parent.OperationName);
628684
Assert.False(a.HasRemoteParent);
685+
Assert.Empty(a.Baggage);
629686
});
630687
}
631688
}

0 commit comments

Comments
 (0)