Steve Hebert's Development Blog

Sponsors

The Lounge

Wicked Cool Jobs

Currently Reading

My Amazon Wish List

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
Asynchronous Webservice Calls – the Truth behind the Begin… End… functions – Part II
In my previous post on this topic,  I concluded with three key points:
  • The Begin function does not actually initiate the physical call on the wire – it simply places these calls into a queue to be processed later. 
  • Due to point #1, if you are making multiple asynchronous calls while varying the parameters on an input struct or class, you must deep-copy that structure before passing.
  • Due to a maximum of two calls being made at any one time,  I recommended that you handle the asynchronous calls yourself via a threadpool. 

 

While the first two points hold, it turns out the maximum number of simultaneous calls is, in fact, a way of playing nice. As I mentioned in the earlier post, flooding a public server with too many simultaneous requests may result in being pegged as a DoS attack. Thanks to SecretGeek's comments and  Tomas Restrepo's blog entry, they opened some questions with my conclusions pointing to their own experiences around connection handling.


If you wish to pipeline requests, you need to look at key issues with setting up the client machine and the server.  Unfortunately, the client-side still uses multiple threads to handle the requests (instead of using overlapped IO), but at least I don't have to manage the threadpool myself.  


Configuring the Client

 

The client can handle more than two simultaneous asynchronous requests and the configuration bits lie in machine.config.  By default, the maxconnection setting within .Net is defaulted to “2” for any given address/port. You can change this setting system-wide or specify configurations for specific addresses.   

 

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

 

Setting this value to “20” allows all requests on the test call I put together to be fired simultaneously.  (Note that I couldn’t get this to actually work with more than 10 on my development box – reasons below.) Keep in mind that in setting this value, you must also be mindful of a host of other threading settings – maxWorkerThreads, maxIOThreads, minFreeThreads and minLocalRequestFreeThreads.  For a more thorough discussion on this topic, check out Tess’ blog entry on this topic

 

Configuring the Server

 

Getting these requests to be serviced simultaneously under IIS 5.x and Windows XP is another story.  When I set the maxconnection setting, my local IIS webserver responded with a 403 error.  It continued responding with the 403 error for several minutes. 

 

Feeling like a server error, I verified the problem in a KB article stating that IIS is honoring the 10 connection limit of XP Pro.  The KB does mention that turning off HTTP Keep-Alives under IIS will improve the performance in this instance, but I didn’t see any changes when trying to set maxconnection to anything larger than 10.

 

I’m on vacation this week, so I’m not sure how Win2k3/IIS6 will respond with a flood of webservice calls and how HTTP Keep-Alives play into this performance.  That will be a posting for another day.

 


Posted Thu, Jul 20 2006 9:24 PM by shebert

[Advertisement]

Comments

Steve Hebert's Development Blog wrote Asynchronous WebService calls – the truth behind the Begin… End… functions
on Thu, Jul 20 2006 10:45 PM
I’ve finally solved this one – not that the resolution makes
me happy, but it’s nice to finally explain...
Sam Gentile wrote New and Notable 111
on Fri, Jul 21 2006 10:20 AM
Sipping the first cup of coffee, ah yes, there's a possibility I'll be awake soon...
Windows Vista ...
Udi Dahan - The Software Simplist wrote re: Asynchronous Webservice Calls – the Truth behind the Begin… End… functions – Part II
on Fri, Jul 21 2006 1:08 PM
Wouldn't it be great to just use a transport which is inherently asynchronous and doesn't have any of these limitations?

MSMQ is one such transport. There is even a binding for it if you want to use WCF. You could even configure it to go over HTTP so that firewalls wouldn't be an issue.

I wonder why Microsoft doesn't talk about it much, since it's really the only transport they have that's suitable for enterprise apps. It's either that or Tib's RV.
shebert wrote re: Asynchronous Webservice Calls – the Truth behind the Begin… End… functions – Part II
on Tue, Jul 25 2006 11:11 AM
It seems that ever since SOAP hit 1.0 back in 2000, that the switchable transport layer capability took a back seat.  I get the feeling it was that people had a hard enough time grasping the concept that they backed of the idea of saying "hey, you can transport these over any channel - SMTP, MQ, etc)".

For my needs the MSMQ transport isn't a good fit, but it's a good design consideration that commonly gets overlooked.



Steve Hebert's Development Blog wrote Asynchronous Webservice Calls – the Truth behind the Begin… End… functions – Part III
on Thu, Mar 15 2007 10:15 AM

After getting a few questions about the solution to invalid return values that I mentioned in the original

Interesting finding - 03/15/2007 « Another .NET Blog wrote Interesting finding - 03/15/2007 &laquo; Another .NET Blog
on Thu, Mar 15 2007 8:16 PM
Devlicio.us