Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/OpenTelemetry.Api/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

## Unreleased

* **Breaking change** `RuntimeContext.ContextSlotType` can only be assigned one
of the following types: `AsyncLocalRuntimeContextSlot<>`,
`ThreadLocalRuntimeContextSlot<>`, and `RemotingRuntimeContextSlot<>`. A
`System.NotSupportedException` will be thrown if you try to assign any type
other than the three types mentioned.
([#4542](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4542))

## 1.5.0-rc.1

Released 2023-May-25
Expand Down
52 changes: 48 additions & 4 deletions src/OpenTelemetry.Api/Context/RuntimeContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,40 @@ public static class RuntimeContext
{
private static readonly ConcurrentDictionary<string, object> Slots = new();

private static Type contextSlotType = typeof(AsyncLocalRuntimeContextSlot<>);

/// <summary>
/// Gets or sets the actual context carrier implementation.
/// </summary>
public static Type ContextSlotType { get; set; } = typeof(AsyncLocalRuntimeContextSlot<>);
public static Type ContextSlotType
{
get => contextSlotType;
set
{
Guard.ThrowIfNull(value, nameof(value));

if (value == typeof(AsyncLocalRuntimeContextSlot<>))
{
contextSlotType = value;
}
else if (value == typeof(ThreadLocalRuntimeContextSlot<>))
{
contextSlotType = value;
}
#if NETFRAMEWORK
else if (value == typeof(RemotingRuntimeContextSlot<>))
{
contextSlotType = value;
}
#endif
else
{
throw new NotSupportedException($"{value} is not a supported type.");
}

contextSlotType = value;
}
}

/// <summary>
/// Register a named context slot.
Expand All @@ -41,6 +71,7 @@ public static class RuntimeContext
public static RuntimeContextSlot<T> RegisterSlot<T>(string slotName)
{
Guard.ThrowIfNullOrEmpty(slotName);
RuntimeContextSlot<T> slot = null;

lock (Slots)
{
Expand All @@ -49,9 +80,22 @@ public static RuntimeContextSlot<T> RegisterSlot<T>(string slotName)
throw new InvalidOperationException($"Context slot already registered: '{slotName}'");
}

var type = ContextSlotType.MakeGenericType(typeof(T));
var ctor = type.GetConstructor(new Type[] { typeof(string) });
var slot = (RuntimeContextSlot<T>)ctor.Invoke(new object[] { slotName });
if (ContextSlotType == typeof(AsyncLocalRuntimeContextSlot<>))
{
slot = new AsyncLocalRuntimeContextSlot<T>(slotName);
}
else if (ContextSlotType == typeof(ThreadLocalRuntimeContextSlot<>))
{
slot = new ThreadLocalRuntimeContextSlot<T>(slotName);
}

#if NETFRAMEWORK
else if (ContextSlotType == typeof(RemotingRuntimeContextSlot<>))
{
slot = new RemotingRuntimeContextSlot<T>(slotName);
}
#endif

Slots[slotName] = slot;
return slot;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public void EnsureAotCompatibility()
Assert.True(process.ExitCode == 0, "Publishing the AotCompatibility app failed. See test output for more details.");

var warnings = expectedOutput.ToString().Split('\n', '\r').Where(line => line.Contains("warning IL"));
Assert.Equal(43, warnings.Count());
Assert.Equal(40, warnings.Count());
}
}
}