SOAP Is So Tricksy

I started to code in .Net at work a while ago, yes yes have a laugh at me, I still kick your ass in Assembly ;) Anyway, we use SOAP heavily and it is really wrapped well in C#, you invoke the remote methods seamlessly as if they were a local interface/methods to use. We wanted to see the performance of our server, so I wrote some simple stress tests in C#, of course. I configured my IIS to work with my SOAP libraries and started running the tests. Then after a long long while, an exception is thrown from the server notifying me that the session is null. Needless to say, our service needs authentication and stores some info about it (it requires a login before usage). I wasn’t sure why the session is dropped, because all other connections kept on working and invoking methods on the server. So something here was fishy. I googled for ‘dropped sessions’ and all the stuff I could find about .Net, IIS and Sessions. They gave tips like check the Event Viewer for logs that the server is recycling etc. Looking at the Event Viewer of the server I didn’t find anything special nor any indication that something happened to the server. And no, the server wasn’t recycling cause otherwise all the other connections would have dropped at the same time as well as that one I saw, therefore I eliminated options like the files in the virtual directory of the services were changed or scanned… (Some weird feature of the ASP.Net Web Service, go figure). Eventually I sniffed my own network with WireShark and since I was stress-testing the server I gathered loads of packets in a jiffy, realizing it’s not the way to go. However I managed to catch the exception while sniffing the connections (while restarting the sniffing every few seconds… :) ) and analyzing the data yielded that the client (that is, my test app) used out of the blue some session id that I didn’t see earlier in the same log I captured (mind you I didn’t have the full log). Spooky something. I did the test again, and got same results. Then I thought why not to change the session time of my webservice in IIS to 1 min. You guessed it right, it so happened that the problem occurred more frequently, so now I was sure the problem is in my code and not something wrong configured with the server or the client uses random sessions ids for some reason… never know with bugs, you know, especially when you stress-test. hihi

The next thing I was doing, since I didn’t want to sniff the whole session of the connection(s) was to add some code for logging the time of last method-invocation and when that null session exception is thrown to see how many seconds have elapsed since that last invocation. Immediately it showed that some invocation happened after 1 minute, meaning the session at the server is already expired and yet the client would still use that same session id it got from the beginning. Every connection was made from a different thread, and each thread could talk to a few webservices at the same time. When the exception is thrown I know which webservice/method raised it and to that function I added the last time thingy.

In the end, I had some ‘if random(100) < 1’ that resulted in true only after some time in a while, the bug didn’t surface up from the beginning cause everytime that it did the invocation of the remote method, the session time out will be reset, but some rare times, the invocation hasn’t occurred for more than the default session time-out (20 mins)  and thus the exception and dropped connection.

The solution was simple, though we had two options: To add cookies to the client side so we don’t need a session at the server, and even if the session is expired the server will still recognize our cookie and serve us well. The other solution, which was simpler now, was to call the login method again to re-initialize the authentication, which really creates the Session at the server side and everything works better now.

I had this stupid bug because SOAP is wrapped so nicely in .Net that you don’t ‘feel’ it, nor even remember that you use a server here, I really mean it guys. So why in the world should I call login after I did it once in the initialization?! Now I got a reason, apparently :)

Leave a Reply