TraceContextBase GetParentTraceContext()

in src/DurableTask.AzureStorage/AzureStorageOrchestrationService.cs [884:947]


        TraceContextBase GetParentTraceContext(OrchestrationSession session)
        {
            var messages = session.CurrentMessageBatch;
            TraceContextBase parentTraceContext = null;
            bool foundEventRaised = false;
            foreach(var message in messages)
            {
                if (message.SerializableTraceContext != null)
                {
                    var traceContext = TraceContextBase.Restore(message.SerializableTraceContext);
                    switch(message.TaskMessage.Event)
                    {
                        // Dependency Execution finished.
                        case TaskCompletedEvent tc:
                        case TaskFailedEvent tf:
                        case SubOrchestrationInstanceCompletedEvent sc:
                        case SubOrchestrationInstanceFailedEvent sf:
                            if (traceContext.OrchestrationTraceContexts.Count != 0)
                            {
                                var orchestrationDependencyTraceContext = traceContext.OrchestrationTraceContexts.Pop();
                                CorrelationTraceClient.TrackDepencencyTelemetry(orchestrationDependencyTraceContext);
                            }

                            parentTraceContext = traceContext;
                            break;
                        // Retry and Timer that includes Dependency Telemetry needs to remove
                        case TimerFiredEvent tf:
                            if (traceContext.OrchestrationTraceContexts.Count != 0)
                                traceContext.OrchestrationTraceContexts.Pop();

                            parentTraceContext = traceContext;
                            break;
                        default:
                            // When internal error happens, multiple message could come, however, it should not be prioritized.
                            if (parentTraceContext == null || 
                                parentTraceContext.OrchestrationTraceContexts.Count < traceContext.OrchestrationTraceContexts.Count)
                            {
                                parentTraceContext = traceContext;
                            }

                            break;
                    }                   
                } else
                {

                    // In this case, we set the parentTraceContext later in this method
                    if (message.TaskMessage.Event is EventRaisedEvent)
                    {
                        foundEventRaised = true;
                    }
                }            
            }

            // When EventRaisedEvent is present, it will not, out of the box, share the same operation
            // identifiers as the rest of the trace events. Thus, we need to explicitely group it with the
            // rest of events by using the context string of the ExecutionStartedEvent.
            if (parentTraceContext is null && foundEventRaised)
            {
                // Restore the parent trace context from the correlation state of the execution start event
                string traceContextString = session.RuntimeState.ExecutionStartedEvent?.Correlation;
                parentTraceContext = TraceContextBase.Restore(traceContextString);
            }
            return parentTraceContext ?? TraceContextFactory.Empty;
        }