Hi, I've been meaning to write an article about how I used Apache/mod_perl to implement a mobile SMS application platform as it demonstrates use of Apache/mod_perl outside the Web realm, something I hadn't seen so far. Time constraints (as always) have prevented me from doing this properly, however, I'll try to give a short description of the system.
The goal kinda is to see if others are using Apache/mod_perl in a similar way to share experiences, discuss issues that arise or discuss alternatives (I'd love someone to tell me I'm an idiot for handling all this lowlevel stuff myself and move to J2EE/java at once, if he can convince me I could have implemented this with the same budget and time frame). Introduction ************* The purpose of the application is to provide a server platform on top of which arbitrary SMS applications can be developed quickly and provide a stable and scalable architecture that allows for future enhancements such as integrated billing and reporting options. An SMS application can be characterized by subscribers sending text-based commands to the platform, have the platform dispatch to the right application instance. The application instance handles the command, executing whatever application-logic defined for the particular application, and usually generate responses to the subscriber command. It should also be possible that the platform initiates messages to subscribers as a result of a command from another subscriber as well as be able to generate messages based on timers Connecting the platform to external entities for the transmission and reception of SMS messages such as SMSC's (SMS center; these things distribute SMS messages directly to and from mobile subscribers) and SMS Gateways (really a "smart" front-end to one or more SMSC's, unifying the way to reach subscribers from multiple telco's) should be flexible enough to be able to "plug-in" different protocols such as HTTP/SMTP/CIMD/SMPP as needed. All persistent data needed by SMS applications must be stored in the underlying RDBMS. The server platform must provide access to the persistent storage to the SMS applications. Component architecture ************************** Early on in the project I decided to go for a distributed component architecture such that individual components can be deployed over various physical machines. This will offer the required scalability as well as allow for a convenient security scheme by allowing components to run on segments of a network with differing outside visibility. As I started modelling this "world", I ended up with the following components: 1. game application server Within this application server, multiple instances of multiple SMS application classes should be running. This component provides two external services: - handleMessage(CommandRequest) This service takes an instance of a CommandRequest object and runs the command in the appropriate application instance. - handleTimer(Timer) This services handles expiry of a timer set by the application logic. 2. timer service A persistent service that maintains timers set by application instances within the game application server and invokes the handleTimer service of the game application services upon expiry of a timer. External service offered: - setTimer(Timer) 3. virtual SMS gateway This component is handles communication with the outside world (the external entities such as SMSC's and SMS gateways). This component is split up in 2 subcomponents, one that handles input from mobile subscribers and one that handles output to mobile subscribers. Each subcomponent provides one service: - handleMessage(Message) The input component receives requests from the outside world using pluggable subcomponents that handle protocol details, the output component transmits requests to the outside world using pluggable subcomponents that handle protocol details. Apache/mod_perl component containers ******************************************** When thinking about how to implement all this I was tempted to look into doing it with some J2EE-thingy. However, there was this time-constraint as well as a constraint on available programmer-hands (I tricked management into hiring one programmer for 20 days, the rest I had to do by myself). Then it struck me that this game application server really looked like a vanilla regular mod_perl web application: receive request from user, process, send back reply. No html though, but Message objects that could be serialized/deserialized from text strings. There were of course some differences: the reply is not sent back inline (i.e. upon reception of a request via SMS, you can't "reply"; you have to create a whole new message and send that to the originator of the message) and there was this timer service: I can't make Apache/mod_perl do work without having it received a user-initiated request. The good thing was I've been doing Apache/mod_perl for some years so I knew beforehand I could create a schedule acceptable from the business point of view that was also feasible based on experience with the technology. So, for each component except the timer service, I created physical Apache/mod_perl instances, one for the game application server, one for the SMS output component and one for the SMS input component. Each instance really only defines one or two URL's that access the service provided by the component running in the instance. Component communication ****************************** I took a shortcut here. I really wanted to go for SOAP here as it's a natural fit and it will allow me to move components to other languages (management and marketing still seems hung up on java) fairly easy. My personal experiences with SOAP on earlier projects weren't too good and I just couldn't fit playing with SOAP into my schedule. So I took my old friends LWP::UserAgent, HTTP::Request and Storable to handle this part (perl object instance -> Storable freeze -> HTTP post -> Storable thaw -> perl object instance). The good thing is that this is a minor part of the whole system and I know I can put SOAP in easily when the need arises. Result ******* We had the platform in place in about 6 weeks, starting with absolutely nothing: no hardware, no development environment, no technology choices made beforehand. Also based on former experience, the decision to go with a LAMP architecture (Linux, Apache, MySQL, Perl) running on fairly cheap intel boxen was made quickly. MySQL was, and is, not on my wishlist, but the whole battle of moving Oracle in would be both a time and money killer, either of which we didn't have a lot of at the time. Aside from having one production SMS application (a mobile SMS game), I've done a prototype SMS application on this platform to check if it really is easy to create new apps. It took me about 4 hours to implement a "SMS unix commandline" application: I can login to the application server using SMS, send Unix commands with my mobile phone and receive their output (better make sure your command doesn't generate more than 160 characters though), the application maintains my working directory etc.. Performance is 'good enough' with the platform running on 2 cheap Intel boxen, it handles 40 to 60 incoming commands per second. As I haven't spent one second on optimization yet (anyone know the command to create an index in MySQL? :)), that number is fine for me. Future enhancements and considerations ********************************************* I really want SOAP. It just seems to make sense to do so as I expect the number of components to grow as well as some non-perl components. To handle a large number of concurrent transactions in a transaction-safe environment without me having to worry too much about concurrency issues and referential integrity I will slowly move to Oracle. $dbh->do('LOCK TABLE USER, INSTANCE, APP_DATA') just plain sucks unless you want to create a very large distributed *single-user* system running on multiple machines. I want a discrete layer between Apache/mod_perl and the game application server so that I really get a generic application server with multiple application instances providing services. running . I'd also like a better way of describing the services that each application provides. Some things in the current system are not abstract enough for my taste; some parts of the code still look too much like a web server and I don't do no stinkin' web stuff ;) I'm still unsure about LAMP. Can we move to very cheap hardware and a free OS when we were used to expensive HP, Sun or IBM stuff that was *expensive* and get away with it? Personal experience and what I've read seem to indicate we can. Live experience will tell, and if it breaks, moving the platform to either of the above three should be a no-brainer. We live in interesting times. Well, that's it. Fairly longish story and yet there's a lot more to tell. Maybe this has been interesting for some, maybe some people on this list did similar things, I'd love to get feedback, Best regards, Bas Schulte.