javajunky
06-15-2007, 11:08 AM
I have a service in my Spring app that executes long running web-service calls (this is all it does, it is very lightweight, just acts as a proxy).
However the default behaviour of Asp.Net web services when exposed is to consume a worker thread from the pool, which after 25 or so requests (12 in my case due to an unrelated issue with maxconnections *sigh* ) locks the system so it can no longer receive requests.
Now, I've written around this by creating my own ASMX Handler factory, that constructs IHTTPAsyncHandler derived classes rather than IHTTPHandlers, each of which consumes the IHTTPHandler that the Spring.Web.WebServiceHandlerFactory would have provided when called for .asmx .
This works really well, and free's ASP.Net to handle parallel web requests whilst these long running requests work in the background. (Just ask if anyone wants some example code)
*However* whilst researching these issues I'm seeing ([1],[2]). I came across a neater approach which was rather than exposing
[WebMethod]
public string MyMethod()
if you expose
[WebMethod]
IAsyncResult BeginMyMethod(AsyncCallBack cb, object obj, ...parameters...)
[WebMethod]
string EndMyMethod(IAsyncResult result)
Then the wsdl would only expose a single 'MyMethod' method that returned a string, and when called the web-service would be handled seperately to the threads consumed by the requests.
For me this is very useful as it allows the system to continue handling and responding to requests even when it is 'busy' servicing many long-running requests. Which is very important so I can respond to requests with a 'too busy' response when I really am too busy, rather than just ending up in a big request queue.
Clearly this approach isn't suitable for every WebService method, but there are some cases where it would be very useful. e.g. When calling another remote web-service request, inline [my case].
I figure I can implement this by extending the existing WebServiceExporter, would this be a useful thing to work on, or should I stick with my (currently working) AsyncHandlerFactory approach ?
Many thanks,
-- Ciaran
[1] : http://blogs.msdn.com/tess/archive/2006/02/23/537681.aspx
[2] : http://msdn2.microsoft.com/en-us/library/ms998562.aspx#scalenetchapt10_topic9
edit: Hmm, as an added complexity, the BeginMyMethod call would need to grab + store the HttpContext.Current in order to set it back in the thread that handles the asynchronous work or WebApplicationContext.Current won't be at all happy.
However the default behaviour of Asp.Net web services when exposed is to consume a worker thread from the pool, which after 25 or so requests (12 in my case due to an unrelated issue with maxconnections *sigh* ) locks the system so it can no longer receive requests.
Now, I've written around this by creating my own ASMX Handler factory, that constructs IHTTPAsyncHandler derived classes rather than IHTTPHandlers, each of which consumes the IHTTPHandler that the Spring.Web.WebServiceHandlerFactory would have provided when called for .asmx .
This works really well, and free's ASP.Net to handle parallel web requests whilst these long running requests work in the background. (Just ask if anyone wants some example code)
*However* whilst researching these issues I'm seeing ([1],[2]). I came across a neater approach which was rather than exposing
[WebMethod]
public string MyMethod()
if you expose
[WebMethod]
IAsyncResult BeginMyMethod(AsyncCallBack cb, object obj, ...parameters...)
[WebMethod]
string EndMyMethod(IAsyncResult result)
Then the wsdl would only expose a single 'MyMethod' method that returned a string, and when called the web-service would be handled seperately to the threads consumed by the requests.
For me this is very useful as it allows the system to continue handling and responding to requests even when it is 'busy' servicing many long-running requests. Which is very important so I can respond to requests with a 'too busy' response when I really am too busy, rather than just ending up in a big request queue.
Clearly this approach isn't suitable for every WebService method, but there are some cases where it would be very useful. e.g. When calling another remote web-service request, inline [my case].
I figure I can implement this by extending the existing WebServiceExporter, would this be a useful thing to work on, or should I stick with my (currently working) AsyncHandlerFactory approach ?
Many thanks,
-- Ciaran
[1] : http://blogs.msdn.com/tess/archive/2006/02/23/537681.aspx
[2] : http://msdn2.microsoft.com/en-us/library/ms998562.aspx#scalenetchapt10_topic9
edit: Hmm, as an added complexity, the BeginMyMethod call would need to grab + store the HttpContext.Current in order to set it back in the thread that handles the asynchronous work or WebApplicationContext.Current won't be at all happy.