-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Background and motivation
People need to be able to set the (async local) current activity context for parenting without being forced to create/start an activity. In OTel this is referred to as "attach context".
In my particular use case, I re-obtain activity context and baggage via OTel propagation in a general library, and I need to set that context as the "current" context for implicit parenting by all basic uses of ActivitySource.CreateActivity and ActivitySource.StartActivity downstream. I cannot afford to create an activity every time just to get the parent context on the implicit async local nor is it reasonable for me to ask all users of the application to use create/start overload and manually access my custom ActivityContext.Current async local for every activity created.
An ActivityContext.Current would be defaulted in the internal ActivitySource.CreateActivity if it's present after choosing the context on the current activity. That way existing behavior remains the same as today. So what was effectively var context = contextParam ?? Activity.Current?.Context would become var context = contextParam ?? Activity.Current?.Context ?? ActivityContext.Current.
API Proposal
public readonly struct ActivityContext
{
// ...
public static ActivityContext? Current { get; set; }
}It is up for discussion whether ActivityContext.Current getter should return the Activity.Current?.Context if there is not an explicit async local one.
API Usage
public void MyThing()
{
var existingActivity = Activity.Current;
var existingContext = ActivityContext.Current;
Activity.Current = null;
ActivityContext.Current = DeserializeFromPropagatedCarrier();
try
{
RunDownstreamCode();
}
finally
{
Activity.Current = existingActivity;
ActivityContext.Current = existingContext;
}
}With that, I have effectively performed attach context without starting a new activity.
Alternative Designs
An alternative approach would be to support creating an activity from a context, but that may be more confusing/problematic because people expect activities to be created where they start and not be able to be rehydrated from a context.
Risks
Primary risk is user confusion of knowing which implicit context is used for parenting by default at create/start activity call.