I love a good problem. For some reason I seem to run into problems more often then most people. That's not really true, but I ignore less problems then most people. I think most people are able to ignore problems through some sort of rationalization process, but I on the other hand welcome a challenge.
Today I ran into a good challenge, or at least it seemed like one at the time. Once you figure a problem out it's usually so obvious you wonder why it took so long to come up with a solution. I like complex multi-part problems the best because you have to really dig into things and try to understand what's going on at multiple levels. The more difficult or strange the problem the better!
I came in one morning to find there were several red builds, and I jokingly said, "I hope I didn't checkin any code!" I wasn't worried about making such a loud statement, the code I checked in was bullet proof and I was sure of it. As Murphey's law would have it, that doomed me right then and there. Someone responds back, "you broke the build!" I thought surely they were joking so responded back with "yeah right", but I had to go check TeamCity _just_ to make sure.
What the hell?! There it was, my sole checkin for that build broke a single SAML integration test. SAML? I hadn't touched any code directly related to SAML, but somehow my checkin broke it. Running the tests locally produced 8 errors, not just one like on the build agents. After some digging into the local failures I realize that 7 of them are failing because they can't find any errors getting logged. Some of our SAML tests produce errors on the server and then validate they're getting logged correctly since they are important for troubleshooting and verification. I ask another engineer about the logging changes he made the day before, "logging works just fine." So I figure its a problem with my machine so I grab latest source and rebuild. Try again. Still not working!
OK, time to debug into the logging, there's something wrong here. Some logging was working just fine, but the loggers in our http modules were failing to log to the correct appenders. It turned out that the http modules static logger instances were getting initialized before Application_Start, which meant the default (and wrong) logger was getting injected into our http modules because we configure our logging on application start. Fortunately the other engineer was able to quickly fix the issue once I explained the problem to him.
With that out of the way I could finally get back to my original test failure... or so I thought. Trying to run the entire SAML fixture locally would always hang after the tenth test; a timeout would occur after a minute and a half. But why? It works fine on the TeamCity agents. Is it just my machine again? I suppose this is where I differ from most engineers. I suspect most engineers would go down the path of "it must be my machine and the test passes if I run it by itself". Not me! I need to know why its failing for fear of a real production defect, but more importantly I need to satisfy my curiosity.
I start by cleaning up the test suite to ensure there's not some strange interaction going on between tests. I attach a SQL trace, turn up logging, attach a debugger, add logging statements, start hacking on the SAML production code, turn off session state. Still nothing! I can see in the debugger that the code being executed on several threads is not managed and it's certainly not mine, so what the heck is going on?
Then I get an idea, this repros consistently after 10 web requests from my test suite, lets see what has a limit of 10 in our system? I start adding all the relevant ASP.NET performance counters I can find. Nothing. No requests being rejected, no requests being queued. Nothing. So I decide its time for a little help, so I Google IIS 7.5 request limit and find a thread that refers to a limit of 10 on Windows 7. That's interesting I have Windows 7 and the build agents have Windows Server 2008. Aha!
I look at the test suite again, but wait I'm only making one request at a time. Maybe the WebResponse connections aren't getting closed? I add response.Dispose(). Nope, it won't compile. I guess that answers why the previous developers didn't dispose the responses. Maybe response.Close()? Aha! There is a close method and even better when I run the test suite now it doesn't hang anymore!
Why would an object like that not implement IDisposable? Let's disassemble the HttpWebResponse. Aha! It does implement IDisposable, but it does so explicitly! That means you need to cast HttpWebResponse to IDisposable before you can call Dispose!
I understand why you'd want to use explicit interface implementations, but in this case it seems like a way to build an API that allows developers to shoot themselves in the foot easily. If you read the documentation it clearly states you should call Close() or you may run out of connections, but still most developers are going to go look for the explicitly implemented Dispose method first.
Coding on stilts
Me trying not to fall in and get hurt.
Friday, May 18, 2012
Thursday, April 19, 2012
Android Emulator Hosts File Entry
Getting the ice cream sandwich Android emulator working on my Mac against my Parallels VM hosted Windows web site was a PITA. I had to follow these directions to add a hosts entry (with slight modification): http://www.bradcurtis.com/2011/02/13/hosts-file-google-android-emulator/
I had to use the partion-size of 256 and ensure my hosts file had a newline after my entry, and for whatever reason without the newline after my VM host entry or the tabbing between the IP and host screwed things up.
Thursday, April 12, 2012
I'm Now a ServiceStack Contributor
I'm now officially a ServiceStack contributor! The ServiceStack guys, in particular Mythz, are super responsive both on GitHub and on chat. After submitting my pull request to fix an XSS vulnerability, I don't think it took them even an hour for them to list me as a contributor.
Without a doubt ServiceStack has simplified and sped up our development of .NET implemented REST services.
Commit VisualStudio Edited Files from OSX
Recently I needed to submit a patch to the ServiceStack project, a .NET services library. I use Git on my Mac to checkout source to my Mac HDD and then use Visual Studio to edit the source. This is however not without some complications.
Visual Studio being a Windows app likes to add carriage returns to everything, so when I go to diff on my Mac I see line ending errors (^M) on every new line I've added. Fortunately GitHub has some pretty darn good help on this subject.
The way around this is to ensure you commit using line feeds only (strip out CRs) and then you also need to have git diff ignore CR before you commit. These are the settings I used:
git config --global core.autocrlf input
git config core.whitespace cr-at-eol
Globally I want to ensure I always commit using LF only on my Mac. Secondly I don't want to see CRLF errors when diffing something edited by VS in this repo (before commit, after commit these CRs are removed).
Visual Studio being a Windows app likes to add carriage returns to everything, so when I go to diff on my Mac I see line ending errors (^M) on every new line I've added. Fortunately GitHub has some pretty darn good help on this subject.
The way around this is to ensure you commit using line feeds only (strip out CRs) and then you also need to have git diff ignore CR before you commit. These are the settings I used:
git config --global core.autocrlf input
git config core.whitespace cr-at-eol
Globally I want to ensure I always commit using LF only on my Mac. Secondly I don't want to see CRLF errors when diffing something edited by VS in this repo (before commit, after commit these CRs are removed).
Tuesday, March 27, 2012
Pull request workflow via GitHub
I often forget what best practice is; so I don't forget the basic process is:
- Open an issue
- Fork
- Clone the fork
- Add a remote upstream track branch to pull in updates
- Create a branch to work in (you can only have 1 pull request per branch)
- Commit your changes
- Optionally squash your commits with Git rebase
- Submit a pull request
Sunday, March 18, 2012
JS/CC Lexer and Parser for JavaScript
From the browser I need the ability to turn user input into a graphical representation. The user will be using a very simple DSL to do this, but using a bunch of regex and standard string parsing just doesn't feel right for long term maintenance.
I'm going to give JS/CC a shot and see if what I come up with. Even if it doesn't elegantly solve my current problem it may prove useful down the road for other problems. Besides, you're not a real geek unless you've written your own language.
Tuesday, January 31, 2012
Git Command Line Log Graph
Git is really powerful, but at the same time I keep forgetting a lot of the commands that I don't use every single day. Today I'm going to try and remember the log command, specifically with the --graph option. It is similar to the GitHub network graph but available from the command line, which is great when you need to merge or rebase.
git log --graph --pretty=oneline --abbrev-commit
* 191a001 Added *sass-cache/ to .gitignore.
* 9ddd799 Added a TODO, this comment needs more detail.
* ba4ca36 Added instructions on how to run the unit tests.
* 8f45ce6 Use watermarks instead of labels on the login form.
* 4911a63 Merge remote-tracking branch 'origin/master'
|\
| * 4038546 Upgraded SenchaTouch2 library from PR3 to PR4
* | f89ecc8 README updated with more detailed info about...
|/
* 79f464c Added login form
* b593038 Added logo that has a solid background color
--pretty=oneline prints each commit on a single line, which really helps readability.
--abbrev-commit truncates the hash of the commit, since its not all that important most of the time.
git log --graph --pretty=oneline --abbrev-commit
* 191a001 Added *sass-cache/ to .gitignore.
* 9ddd799 Added a TODO, this comment needs more detail.
* ba4ca36 Added instructions on how to run the unit tests.
* 8f45ce6 Use watermarks instead of labels on the login form.
* 4911a63 Merge remote-tracking branch 'origin/master'
|\
| * 4038546 Upgraded SenchaTouch2 library from PR3 to PR4
* | f89ecc8 README updated with more detailed info about...
|/
* 79f464c Added login form
* b593038 Added logo that has a solid background color
--pretty=oneline prints each commit on a single line, which really helps readability.
--abbrev-commit truncates the hash of the commit, since its not all that important most of the time.
Subscribe to:
Posts (Atom)