Hi all, I've been lurking on this list for quite some time now. When I first ran into the p5ee concept I was excited as I felt I could contribute based on my experience with the issues surrounding perl and enterprise development as I profoundly believe J2EE and it's users (programmers/architects/management) are not the holy grail at all. In fact, I've seen at least two hyped J2EE developments (for which there was enough funding) fail miserably while I, with a very small number-wise but otherwise great team, "sneakily" put in a perl/OO-based system that fullfilled the business requirements just fine.
The reason of this post is Stas Bekman's reaction to an article I posted on the mod_perl mailinglist describing my most recent project. He suggested posting it here as well, so I comply ;) It's about implementing a component/service-based system on top of an Apache/mod_perl combo that has been developed, in time, in a timeframe that even I felt was impossible when I did the initial requirements analysis. Something that is not stressed in the article itself are thoughts I had on the requirements I had in the beginning of the project about having a true perl-based application server. One that allows me to have persistent perl objects handling method calls 'from the outside' in a container application that takes care of instantiating my objects as well as dispatch incoming requests to them etc.. I did read the articles on this list about POE as a candidate for this type of problem but I personally don't think POE fits the bill in a system that wants to offer an alternative to J2EE. At a very low-level it might be good as I never understood the things I read about it, but non-forking and cooperative just don't sound right to me. I'm also agnostic to the 'wheel' terminology ;) Aside from pasting my post below, I hope to contirbute to p5ee regarding the 'multithreaded method serving' issue as well as other component/service-architecture as time permits. Happy reading ;) Bas. ps. I already decided to remove my MySQL vs. Oracle comments in a next version of my story so please don't point me to InnoDB tables in MySQL and/or Postgresql, ok? :) 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 and 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.