Mar 25, 2013 at 7:33 PM
Edited Mar 25, 2013 at 7:34 PM
Here's what I'm seeing during calls to ITraceManager.Initialize:
After this initialize call, I see one MessageHandler in the config - RequestMessageHandlerTracer. Its InnerHandler is null.
- The call to DefaultHttpControllerSelector.GetControllerMaping() calls Get on a Lazy<ConcurrentDictionary<string,HttpControllerDispatcher>>
- Lazy<T>.Get calls LazyInitValue then CreateValue
- Call to DefaultHttpControllerSelector.InitializeControllerInfoCache
- Call to HttpControllerDescriptor constructor
- Call to HttpControllerDescriptor.Initialize
- Call to HttpControllerDescriptor.InvoleAttributesOnControllerType (which calls an overload of itself)
- Call to HttpConfiguration.ApplyControllerSettings
- Call to HttpConfiguration.DefaultInitializer
- Call to ITraceManager.Initialize
After this initialize call, I see three MessageHandlers - two RequestMessageHandlerTracer and one MessageHandlerTracer. No innerHandler loop yet.
- Stack trace looks the same as Initialize #1 - called from within the GetControllerMapping->Lazy->HttpControllerDescriptor.ctor chain.
Now I see 7 message handlers, all tracing. No innerhandler loops. Same stack trace.
15 message handlers, all tracing.
And continuing with each call to ITraceManager.Initialize, counting message handlers:
31, 64, 255, 511, 1023, 2047, 4095, 8191.
The last call to ITraceManager.Initialize was the "8191" call, and is within HttpServer.SendAsync, not Application_Start.
None of the message handlers seem to have an InnerHandler assigned. Looks like it's not truly overflowing on a recursive loop, just a massive number of handlers. The behavior you mentioned about how the number of trace managers "doubles" makes sense
- that's precisely what I'm seeing.
: Web API Tracing installs its "wrapping" MessageHandlers each time HttpConfiguration.ApplyControllerSettings is called. Each time a HttpControllerDescriptor is constructed, ApplyControllerSettings is called (a bug or
design oversight?). Calling "GetControllerMapping" causes a large number of HttpControllerDescriptors to be constructed, and the number of descriptors it creates is dependent on the number of controllers in the assembly. Renaming a small number of
controllers got rid of the StackOverflowException for me since less data was placed in the stack.
The issue probably didn't show up during testing because requests to "$metadata" don't cause the behavior to occur. Perhaps the call to GetControllerMapping() has different behavior during Application_Start.