Thursday, June 14, 2007
« Downloading VMWare Fusion in hopes of du... | Main | acts_as_attachement and attachment_fu no... »
Over the last couple days a number of people on our team have been investigating why an operation marked as one way on one of our WCF services ends up blocking when it's called.  We looked at a number of things with our setup including:
  • Making sure our operation did in fact have IsOneWay=true defined
  • Ensuring none of the behaviors we have setup for exception sheilding and authorization were cuasing the call to block
  • Ensuring that it wasn't something within our client by creating a console app to replicate the problem
  • Validating the configuration on both the client and service side where both correct
  • and more...
Yesterday afternoon Sam and I began to dig into the problem a little deeper by turning on tracing and message logging for our services.  After spending a bit of time tracing through the logs with SvcTraceViewer we eventually spotted something in the client side log that didn't look right.  The entry looked something like this:

Close Secure Session       10s

What was mysterious about this line was that in order to replicate and debug the problem we had a service that looked like this:

[OperationContract(IsOneWay=true)]
public void MyOneWayOperation(ItemRequest request) {
    Thread.Sleep(10000);
}

So it appeared that the Close on channel was actually blocking until our one way operation completed.  We weren't totally convinced that this could really be the case, so we changed our operation like so:

[OperationContract(IsOneWay=true)]
public void MyOneWayOperation(ItemRequest request) {
    Thread.Sleep(20000);
}

which resulted in the following line in our log:

Close Secure Session       20s

This convinced both of us that it was defintely blocking when closing down the client proxy.  At one point in the past we had run one way messages and not seen this behavior though, so what had changed to all the sudden cause our operation with IsOneWay=true set to block?  It turns out that the "problem" was due to a change in the way we used the client proxies.  Previously we had code that looked like this:

MyServiceClient client = RetrieveClientProxy();
client.MyOneWayOperation(new ItemRequest("KLDF992"));

But due to some problems that we've had with secure sessions timing out, and other inconsisitencies we changed our code to:

using(MyServiceClient client = new MyServiceClient()) {
  client.MyOneWayOperation(new ItemRequest("KLDF992"));
} // FYI, Dispose on a ClientBase calls Close

Instead of re-using our client proxies we're now recreating our client proxy every time an operation is called.  This results in our performance not being as great as it could be since the client has to re-establish it's security context on every call, but, it's also resulted in our services being a lot more reliable.  We'd rather have things run slightly slower than have them not work. 

I still don't understand why closing the client proxy would block when calling a one way operation.  Since a one way operation immediately returns a 202 letting the client know that it was received I'm unsure of why the proxy needs to wait around for the operation to finish when you call Close on it.  It seems to defeat the whole purpose/nature of a one way operation.  I've explicitly said that I don't care about the return value so I don't see why it can't just close when I tell it to. 

 |  | 
Thursday, June 14, 2007 2:29:50 PM (Eastern Daylight Time, UTC-04:00)
Wow, this is weird. I'll definitly have to look into this myself! Thanks for blogging about it!
Friday, June 15, 2007 2:44:30 PM (Eastern Daylight Time, UTC-04:00)
Sorry, don't have time to comment a lot at the moment, but if you check Dr. Nick's blog, this is expected behavior.

J
John
Friday, June 15, 2007 3:56:45 PM (Eastern Daylight Time, UTC-04:00)
http://blogs.msdn.com/drnick/archive/2006/10/18/avoiding-oneway-deadlocks.aspx
Oran
Friday, June 15, 2007 6:36:29 PM (Eastern Daylight Time, UTC-04:00)
The sad part is that I had already blogged that link :)
http://codebetter.com/blogs/sam.gentile/archive/2006/10/19/New-and-Notable-116.aspx
Tuesday, June 26, 2007 8:28:57 AM (Eastern Daylight Time, UTC-04:00)
I am getting the error below when i call the method of the service which is declared as
IsInitiating = false, IsTerminating = true, IsOneWay = true

Error: {"The message could not be processed. This is most likely because the action 'http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT/Cancel' is incorrect or because the message contains an invalid or expired security context token or because there is a mismatch between bindings. The security context token would be invalid if the service aborted the channel due to inactivity. To prevent the service from aborting idle sessions prematurely increase the Receive timeout on the service endpoint's binding."}

Once IsOneway is changed to false, its working.
Happened to read your post when I was looking into why it was happening.

Vidhya
Sunday, March 23, 2008 1:48:01 AM (Eastern Daylight Time, UTC-04:00)
<a href="http://rycexe.com">cazoke</a> | [url=http://cepyhe.com]xekysa[/url] | [link=http://sipoko.com]zixopy[/link] | http://tyxyna.com | cuzovi | [http://hurypu.com cesive]
Name
E-mail
Home page

Comment (HTML not allowed)  

Enter the code shown (prevents robots):