{"id":433,"date":"2008-06-26T22:27:46","date_gmt":"2008-06-26T21:27:46","guid":{"rendered":"http:\/\/wp.devco.net\/?p=433"},"modified":"2009-10-09T13:59:38","modified_gmt":"2009-10-09T12:59:38","slug":"adventures_with_ruby","status":"publish","type":"post","link":"https:\/\/www.devco.net\/archives\/2008\/06\/26\/adventures_with_ruby.php","title":{"rendered":"Adventures with Ruby"},"content":{"rendered":"
Some more about my continuing experiences with ruby, in my last post I said<\/p>\n
the language does what you’d expect and as you’ll see in my next post
\nspending a week with it on and off is enough to write a capable multi
\nthreaded socket server.<\/p>\n<\/blockquote>\nAs it turns out I quickly lived to regret saying that. Soon after I hit publish I started running into some problems with the very same socket server.<\/p>\n
A bit of background, Adobe has made a change<\/a> to how things work moving away from their previous crossdomain.xml<\/i> file served over HTTP for cross domain authorization to a new model that requires you to run a special TCP server on port 834 serving up XML over a special protocol. I won’t go into how brain dead I think this is, suffice to say I needed to run one of those for a client. Adobe of course does provide a server for this, but it has some issues, I chose the simplest of their examples – Perl under xinetd – and quickly discovered that it has no concept of timeouts, or anything that doesn’t speak it’s protocol. The end result is that you just end up with a ever growing number of perl stuff running waiting around for ages.<\/p>\n
I took this as a challenge to write something real under Ruby using it as a learning experience as well, so set out to write a multi threaded server for this. At first glance it looks almost laughably trivial: The Ruby STL includes GServer<\/a> – a very nice class that does the hard work of thread management for you, you just inherit from it and supply the logic for your protocol and let it do the rest, awesome.<\/p>\n
I wrote this, put in logging, options parsing and all the various bits I needed, tested it locally – 10 concurrent workers doing 200,000 requests and it served it in no time at all with limited CPU impact. I then wrote RC scripts, config files and all that and deployed it at my client.<\/p>\n
Real soon after deploying it I noticed the wheels came off a bit. I, out of curiosity, put in some regular logging that would print lines like:<\/p>\n
Jun 23 08:23:37 xmpp1 flashpolicyd[7610]: Had 10042 clients of which 285 were bogus. Uptime 0 days 14 hours 2 min. 23 client(s) connected now.<\/p><\/blockquote>\n
Note in that line how it claims to have 23 connections at present? That’s complete b\/s, I added the ability to dump actual created threads and there just weren’t enough threads for 23 clients and the TCP stack agreed…Turns out gserver has issues handling bad network connections – my clients are over GPRS, Modems, and all sorts – and it seems threads die without GServer removing them from it’s list of active connections.<\/p>\n
This is a small problem except that GServer uses the connection count towards figuring out if you’ve hit its max connections setting. So while I could just set that to some huge figure, it does indicate theres a memory leak – array grows for ever. Not to mention it just leaving me with a bad taste in my mouth over the quality of my new and improved solution.<\/p>\n
Naturally I gave up on GServer I didn’t feel like installing all sorts of Gems on the servers so figured I’ll just write my own thread handling. While it’s not trivial its by far not the most complex thing I’ve ever done. Happy in this case with a bit of wheel reinventing for the sake of learning. <\/p>\n
I chose to use the Ruby STL Logger Library<\/a> for logging and even added the ability to alter log level on the fly through sending signals to the process, very nice and I were able to re-use much of the option parsing code etc from my previous attempt so this only took a few hours.<\/p>\n
I did the development on my Mac using TextMate – the really kick arse Mac text editor that has nice Ruby support – the Mac is on Ruby 1.8.6. I intended to run this on RHEL 4 and 5, they have Ruby 1.8.1 and 1.8.5 respectively, so I was really setting myself up for problems all of my own making.<\/p>\n