Search code examples
wcfdeadlockdotnet-httpclient

WCF and API communication is creating a deadlock (httpClient)


We have a service API (SERVICE) in .netcore 6, a Wcf Services (WCF) in .netframework 4.7.2 and a gateway API (GATEWAY) in .netcore 6. It acts as a gateway to access WCF services

The use case is the following:

1. GATEWAY calls(wcf) WCF/Admin.svc to perform a task
                   2. WCF/Admin.svc calls(api) SERVICE to perform a part of the task
                                            3. SERVICE calls(api) GATEWAY to get some permission info
                                                               4. GATEWAY calls(wcf) WCF/Admin.svc to have the permissions info

calls are stuck on the 4. request. All calls are async, there is no call to .Result

Case 1

We use a shared HttpMessageHandler to connect WCF (using this kind of approach.)

The workflow goes well the first time we execute the workflow.

However, when we call it a second time, the workflow gets stuck. The fourth request is never sent, until timeout of the request 3.

Case 2

We use a new HttpMessageHandler for each request (which is a bad practice). All goes well, all the time.

My guesses

I think that we have either:

  • a request queuing in the HttpClientHandler (which I doubt)
  • a synchronization lock in the httpClient because we have reentrant call that uses the same HttpMessageHandler
  • There is a throttling mechanism in WCF that activates when using the same HttpMessageHandler for reentrant requests

Can we be aware that a call is reentrant?


Solution

  • I finally discovered what was happening:

    In order to make usage of the HttpContext (and other Asp.Net integration) we use the [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] attribute value.

    However this creates a side effect - which in our specific case we are not interested in -, that is creating a ASP.Net Session.

    Upon dong this reentrant loop, asp.net detects that the session is the same and will lock this session state until the first query is over.

    So to make this work, I have added this configuration in the Web.config.

    <system.web>
     <!-- [...] -->
            <sessionState mode="Off"></sessionState>
     <!-- [...] -->
    </system.web>
    

    Now all is working perfectly.