A couple of weeks ago, our first iPhone app went live. It's called Gphushed, and it notifies you, through the magic of Apple Push Notifications, the instant an email arrives in your Google Mail inbox. The app consists of two parts - an iPhone app that you buy that you use to configure the service, and a server, that watches your inbox and sends notifications to Apple when your email arrives.
We wrote the server in Ruby initially. This allowed us to get up and running really fast, but it came back to bite us a little bit. In this article I'll share our experience, because it might be interesting to people out there who are thinking about going down a similar path.
So we chose Ruby for two reasons on the server side -- we like it, and we needed a restful service that the iPhone could interact with (and I can't think of any way of creating a restful service faster than Rails). We added a stompserver, because messaging solves a few problems that we knew we'd come up against (notifiying any listener of changes to an account's configuration, for example). We then wrote the listener, which was effectively an infinite loop that created a new Thread for each mailbox that needed to be monitored.
As you can imagine, this service has many edge cases that need to be handled in an elegant manner, and Ruby let us sketch out the code paths really well. We were using net/imap to monitor the mailbox (monkey patching it to add support for the IDLE command), and while it worked fine in development, it didn't hold up so well in the real world.
We still can't say exactly why our Ruby implementation wasn't reliable, but before we'd even gone live we knew it needed to be re-written. If we left the service running for 24 hours or so, it would silently die. We'd added exception handling, and were trying in vain to capture socket errors and the such like, but everything appeared fine, it just didn't work -- we weren't getting notifications of new messages.
Luckily, Apple's app approval process takes a couple of weeks, so we wrote a proof-of-concept replacement in Java using JavaMail. When we saw that it was good, and that exceptions were consistently thrown (so we knew we'd be able to handle sockets being closed and other unexpected errors), we simple re-wrote the service in Java, using our Ruby implementation as the spec. This worked really well -- we had a complete re-write in two days. The improved exception handling in Java meant that we could better understand the things that were going wrong, and we made many small, incremental improvements to the service that mean it should now be pretty solid.
So do we regret writing it in Ruby? Was that two wasted days? Absolutely not. If nothing else, Ruby allowed us to create a prototype without having to actually worry about the framework. The Java implementation was drastically quicker thanks to the Ruby template that we'd developed -- refactoring and restructuring a Ruby application is much easier than doing the same thing in Java.
The stomp server is still in there, and is working great. We usually use ActiveMQ for messaging, but the stomp clients are incredibly lightweight and appear to be more than good enough for this particular application.
About
We are a small British company that produces business-oriented software and solutions. These articles are a product of our daily work - information that we think might be useful to share. We hope you find them useful.
Our Software
These are some of our products. Several are open source, some are web-based and others are proprietary:
Categories
- .NET (10)
- Apple (2)
- Business (5)
- CSS (1)
- HTML (2)
- Innovation (4)
- Java (4)
- Javascript (1)
- Leadership (1)
- MySQL (2)
- Oracle (6)
- Postgres (1)
- Programming (5)
- Rails (4)
- Ruby (10)
- SQL Server (9)
- Subversion (1)
- Web (5)
- Windows Server (2)
Archives
- July 2010 (2)
- September 2009 (5)
- August 2009 (1)
- July 2009 (12)
- June 2009 (16)
- May 2009 (3)