October 30, 2009
@ 10:58 PM

Yes, this is another WCF rant…

We were getting ready to launch an open-for-all version of our service, we were also adding more cores to the system, to make sure our computation engine will be able to handle higher request loads (We’re basically implementing the Gridable Service pattern -  if it is interesting, I can expand on that in another post). We tried a few load tests, which on first look, seemed OK. However we then noticed that we get WCF timeouts on some of the calls.

WCF timeouts!? what gives? we already took care of all the annoying throttling defaults. After busting my head (and Google) for a few hours, I found that apparently, when using http bindings in WCF you only get 2 outgoing channels for each server (IP) you are connecting to. yep WCF thinks your services are novice users using a  browser. So if you have a service that tries to access a remote server with more than two requests simultaneously (say, under load…) you may find, like us, that you’d get occasional timeouts.

Yes, there’s also a solution, which also took time to find – it is called ConnectionManagment element in the network configuration (I am yet to find a programmable way to do this). So now the services app.config (see below) sets the value to 16 instead of 2 and everything is well again, at least until the next default hits us..

<system.net>
   <connectionManagement>
     <add address = "*" maxconnection = "16" />
   </connectionManagement>
 </system.net>

 

From trying to work with WCF in the last few years, it seems its abstractions are very leaky.They are almost leaky  to the point  of rendering it useless as a “unified” framework. So, in the spirit of the times, and as the title suggest – maybe they should just rename WCF to Windows Trick-or-treat Foundation – Alas, we are getting more and more of the “trick’ part rather that the “treat”, but at least the acronym fits well.


 
Saturday, October 31, 2009 11:53:34 PM (GMT Standard Time, UTC+00:00)
Hi Arnon,
take a look on ServicePointManager.DefaultConnectionLimit property. It shall help for programatic access.

Regards,
Libor
Sunday, November 01, 2009 1:16:19 PM (GMT Standard Time, UTC+00:00)
Thanks :)

Arnon
Monday, November 02, 2009 4:27:51 AM (GMT Standard Time, UTC+00:00)
This one isn't exactly a WCF thing, it's a .NET thing. You'd hit the same limit doing manual REST requests or using any framework that took advantage of the HTTP classes in .NET and didn't override what you had in your config (which at least in my mind would be a bad thing to do).
Monday, November 02, 2009 11:23:04 AM (GMT Standard Time, UTC+00:00)
@Jesse
right - except that WCF is supposed to be a unified framework that masks the specifics. My point is that with WCF I consistently have to worry about the nitty gritty details of the specific bindings. It is only unified at the demo/simple app level
Monday, November 02, 2009 5:51:04 PM (GMT Standard Time, UTC+00:00)
You wouldn't expect WCF to take care every TCP/IP registry setting as well would you? At some point, the things WCF exposes have to stop so transport specific settings come into play. What would really suck is if WCF completely abstracted every detail of every transport and came up with new names for things like cookies and specific http request and response headers in the name of creating a "unified" experience across every transport.

The point of WCF is to give you a unified communication API. You don't have to change your code to switch from HTTP, to MSMQ, to TCP, etc. However, the point of WCF is not to hide all the specifics of each transport from you. There are a lot of transport specific options in WCF that you won't find in a WSDL file. However... none of these settings actually require you to change any code to take advantage of them. IMO, WCF does a really good job of providing a uniform communication API and limiting transport specific details to configuration settings. Even in this case, you were able to resolve the issue by configuration settings rather than code changes.

If you had used http request manually, this is one of very few settings you would actually have control over via configuration. What about other popular competing APIs? Look at something like NServiceBus. NServiceBus has a transport model that abstracts communication to some degree... but what happens when you want to change the format of the messages on the wire? For example, maybe you want to switch from raw XML messages to messages with SOAP envelopes on an endpoint or limit the depth of XML node hierarchies to protect against XML attacks. Maybe you want to switch to a completely new transport that was provided by a vendor that has never seen your product. Maybe you want to add compression, or chunking, or certificate based security. Can you do that all via configuration files without ever touching code in any other .NET API? Maybe this is my own ignorance... but I don't know of any .NET communication API that offers even half of the flexibility of WCF.
Comments are closed.