views:

367

answers:

4

I am working on a class library that retrieves information from a third-party web site. The web site being accessed will stop responding if too many requests are made within a set time period (~0.5 seconds).

The public methods of my library directly relate to a resource an file on the web server. In other words, each time a method is called, an HttpWebRequest is created and sent to the server. If all goes well, an XML file is returned to the caller. However, if this is the second web request in less than 0.5s, the request will timeout.

My dilemma lies in how I should handle request throttling (if at all). Obviously, I don't want the caller sit around waiting for a response -- especially if I'm completely certain that their request will timeout.

Would it make more sense for my library to queue and throttle the webrequests I create, or should my library simply throw an exception if the a client does not wait long enough between API calls?

+2  A: 

That's the Web server's responsibility, imo. Because the critical load depends on hardware, network bandwidth, etc a lot of things that are outside of your application's control, it should not concern itself with trying the deal with it. IIS can throttle traffic based on various configuration options.

cdonner
Surely if your library is to access a web service that will only accept one response per 0.5s, and that is a condition of its use, then it is something you should be concerned with ?
Andiih
If there is some business reason for why you only allow 2 requests per second (maybe because data does not get updated more frequently and the client would not see anything new?), then I would not call that throttling in a sense that you want to limit the load, and that is absolutely something that the application could enforce.
cdonner
The web site being accessed is a third-party site, so unfortunately the IIS settings are out of my control.
Justin R.
+3  A: 

I'd say both - you're dealing with two independent systems and both should take measures to defend themselves from excessive load. The web server should refuse incoming connections, and the client library should take steps to reduce the requests it makes to a slow or unresponsive external service. A common pattern for dealing with this on the client is 'circuit breaker' which wraps calls to an external service, and fails fast for a certain period after failure.

Lee
It would be nice if the request was refused, instead of just ignored. Thanks for pointing me to the circuit breaker pattern, though. I can certainly see times when it would come in useful.
Justin R.
+1  A: 

What kind of client is it? Is this an interactive client, for eg: GUI based app?

In that case, you can equate that to a webbrowser scenario, and let the timeout surface to the caller. Also, if you know for sure that this webserver is throttling requests, you can tell the client that he has to wait for a given time period before retrying. In that way, the client will not keep on re-issuing requests, and will know when the first timeout occurs that it is futile to issue requests too fast.

feroze
The client is a class library, which could be used by a GUI application. Using exceptions to inform the caller that my method is being called to frequently is a solution I'm considering. But I know that frequent calls will cause a timeout, so is it really an exceptional circumstance?
Justin R.
You mentioned that the server throttles requests if "too many requests" are sent withing a certain time (0.5s). How much is "too many requests"?If you think about it, if 0.5s is the limit, then it might be really difficult for the GUI based client to exceed this.Alternately, you can architect your GUI library to have not more than 'N' async requests outstanding, so that you never hammer the server. I would limit N=2 (and make it configurable for your users). And have a mechanism using a delegate to give client progress notifications.
feroze
+4  A: 

The concept of a library is to give its client code as little to worry about as possible. Therefore I would make it the libraries job to queue requests and return results in a timely manner. In an ideal world you would use a callback or delegate model so that the client code can operate in asynchronously, not blocking the UI. You could also offer the option for skipping the queue, (and failing if it operates too soon) and possibly even offer priorities within the queue model.

I also believe it is the responsibility of the library author to default to being a good citizen, and for the library's default operation to be to comply to the conditions of the data provider.

Andiih
+1 for the "good citizen" part. I almost forgot to view this problem from the perspective of the data provider.But then how would I guarantee that results would be provided in a timely manner, without putting a cap of some sort on the number of requests that could be queued?
Justin R.
I dont think you need to guarantee, as long as you provide methods to query the queue size, and perhaps to also have a timeout implemented by the library.
Andiih