Use OneWay for Long-Running Operations
I have a long-running service operation that needs to receive a response. What options do I have for designing my web services?
The problem that most people run into with long-running operations is that the operation eventually hits some quota value and times out. For instance, if you want to run the operation over an HTTP connection, you have to configure the HTTP transport to not give up waiting before the operation completes. This configuration consists of setting the send and receive timeouts of the channel to some maximum bound for the operation time. Setting the timeouts correctly requires you to know what a maximum bound is for your operation. If you don't know of a maximum bound or the expected operation time is poorly defined, then it becomes very difficult to set a reasonable quota value. Quota values that are too small cause the operation to be unnecessarily aborted. Quota values that are too large weaken your security and makes you more vulnerable to malicious attackers tying up your resources.
Large operation times also mean that you're more susceptible to dropped connections or network glitches that cause the operation to be aborted. One alternative to holding a transport channel open during the entire operation is to use an asynchronous delivery mechanism (this shouldn't be confused with asynchronous method calls). Asynchronous delivery, such as a queue, allows you to drop messages off without having a continuously stable network connection to the other party. Reliable messaging is also a way to recover from dropped connections. However, neither of these methods helps you bound your maximum operation time for request-reply style messaging.
The basic solution to unbounding your operation time is to decouple the request and response of the operation into a pair of one-way operations. A one-way operation on the service is used to receive the request and a one-way operation on the client is used to receive the response. Correlation is still needed to associate the request and response together. This correlation is no longer defined by the use of a single network connection but instead is some property associated with the message. Each one-way call has a well-bounded and predictably short operation time.
The one-way model is not perfect. Transports that do not support symmetric message transfer, such as HTTP, are harder to use because you may need to address client machines and poke holes through firewalls. However, that is a tradeoff you may need to make against trying to hold an HTTP connection open for hours on your server until the operation finishes.
If both the client and server are built using WCF and you have a bidirectional transport, then you can use the CallbackContract attribute of the service contract to define a linkage between a service located on the server and a service located back on the client. Using a callback contract makes the programming model easier to use, but you could always build the equivalent functionality yourself if you had to.
Next time: Configuring HTTP for Windows Vista
Comments
Anonymous
October 13, 2006
I have a service that uses Windows authentication and want to impersonate the caller in one of the serviceAnonymous
October 17, 2006
There is so much I want to say about important topics like Rocky's well-written, thought provoking SemanticAnonymous
September 24, 2007
There is so much I want to say about important topics like Rocky's well-written, thought provoking