private async Task ProcessRequestUser(uint requestId) { // this method simulates user code of processing a service request. // Construct a moniker for displaying: const string Indent = " "; string requestMoniker = $"{Indent}[requestTraceId={requestId}]"; for (int i = 0; i < requestId; i++) { requestMoniker = Indent + requestMoniker; } // Simulate work with several async transitions like one would expect for I/O/ for (int i = 100; i < 110; i++) { // This simulates either manual or automatic tracing. I.e., a sub-span is created. MockSpan prevSpan = _currentSpan.Value; _currentSpan.Value = new MockSpan(prevSpan.TraceId, (ulong)i); try { Console.WriteLine($"\n{requestMoniker} [i={i}]" + $" asLoc=\"{_currentSpan.Value}\";" // + $" ThrdInfo.State=\"{CurrentThreadInfo.CurrentState}\";" // + $" ThrdInfo.IsInit={CurrentThreadInfo.IsInitialized};" + $" Before Delay: ThreadId={Thread.CurrentThread.ManagedThreadId}."); await Task.Delay(TimeSpan.FromMilliseconds(500)); Console.WriteLine($"\n{requestMoniker} [i={i}]" + $" asLoc=\"{_currentSpan.Value}\";" // + $" ThrdInfo.State=\"{CurrentThreadInfo.CurrentState}\";" // + $" ThrdInfo.IsInit={CurrentThreadInfo.IsInitialized};" + $" After Delay: ThreadId={Thread.CurrentThread.ManagedThreadId}."); } finally { _currentSpan.Value = prevSpan; } } }
private async Task ProcessRequestSystem(uint requestId) { // This method simulates stuff in the app server.. ulong traceId = requestId; // In reality, obtain traceId from propagated context. MockSpan rootSpan = new MockSpan(traceId, 0); MockSpan prevSpanInfo = _currentSpan.Value; _currentSpan.Value = rootSpan; try { await ProcessRequestUser(requestId); } finally { _currentSpan.Value = prevSpanInfo; } }
/// <summary> /// Ths callback is invoked by AsyncLocal each time the values changed for an underlying physical managed tread. /// The tracer must use a collback timilar to this. /// </summary> /// <param name="changeInfo"></param> private static void OnAsyncLocalValueChanged(AsyncLocalValueChangedArgs <MockSpan> changeInfo) { MockSpan currenActiveSpan = changeInfo.CurrentValue; Console.WriteLine($"\n* AsyncLocalValueChanged." + $" PrevVal=\"{changeInfo.PreviousValue}\"," + $" CurrVal=\"{currenActiveSpan}\"," + $" CtxChange={changeInfo.ThreadContextChanged}," + $" ThreadId={Thread.CurrentThread.ManagedThreadId}."); if (TraceContextTrackerFactory.SingletonInstance.TryGetOrCreateTraceContextTrackerForCurrentThread(out TraceContextTracker tracker)) { if (currenActiveSpan != null) { tracker.TrySetTraceContextInfoForCurrentThread(SpanInfo.ForSpan(currenActiveSpan.TraceId, currenActiveSpan.SpanId)); } else { tracker.TrySetTraceContextInfoForCurrentThread(SpanInfo.ForNoSpan()); } } }