by Ryan Walker

Moving from monolithic legacy to modularized Ruby

Since joining RecruitMilitary two years ago, we’ve been struggling with our progress in moving off our legacy monolithic ASP application.

The legacy ASP app

  • A relatively full-featured job board
  • A career fair system (registration, and a lot of internal reports tracking our progress towards adequate numbers for a successful event)
  • Public web content
  • Client micro-sites (little 4-5 page sites that hooked into their job postings from the job board)
  • CRM for sales team (with tons of little features like sending canned emails from the app, creating/sending invoices to customers)
  • Dashboards (as a sales-driven company, included real-time tracking of key numbers including sales (both cash + accrual) and registration/usage activity of job board + events)
  • Job feed system via XML & FTP that was being used by several dozen clients

Wrapping the old app in Rails

Our first approach was to wrap the app with Rails, with the goal of eventually whittling away the ASP to nothing over time. I really wanted to take a “micro-app” approach, but we spiked a little with that and decided that it would be a lot more work vs. just building one rails app. So we built a big rails app that presently has 54 controllers, 153 models, 10k LOC, 6.5k test LOC.

Plumbing:

  • Legacy database “dual connection” - so our rails app can read/write to the SQL server database as needed

Replacing ASP functionality:

  • New candidate registration process (which then pushes data to legacy database)
  • Public web content
  • XML/FTP processing
  • A variety of dashboard/reports including a relatively simple data warehouse system to make it all fast

Capitalizing on market opportunity/new development:

  • New lead generation system (we have franchise clients, so we built a system to target ads for them)
  • Email marketing system (We send 700,000 emails/month. We had used ExactTarget, then Mailchimp, then had to roll our own because we don’t do double opt in required by Mailchimp.)
  • Job site scrapers (for specific clients)

As we continued through the process of building more into Rails, we were at a precipice where we’d have to start doing 2-way synchronization of data, and the legacy data wasn’t clean, there was bad data modeling in there, and validation was applied inconsistently, so Rails was rejecting records during synchronizations. We cleaned a lot of it up, but still had to transform data during the sync, it was getting complicated.

So we called “time out.”

The end of synchronization

We have decided to abandon the idea that we can build a Rails app that can work with the legacy data and keep the data synchronized as we whittle down the ASP system.

In my ideal world, the new system would include the following characteristics:

  • Not coupled to veteran niche. Ideally we have a system that we can use to move into other attractive niches.
  • Build lots of small, simple apps rather than one big Rails app.
  • Each micro app can stand alone, and is not coupled to being part of the overall system. This allows us to open source it or SAAS it.
  • Not require subdomains for each microapp. We’re thinking we can mount the apps in a master Rails 3 app to accomplish this, or we can take Frederick Cheung’s approach to rewrite the subdomains to subdirectories.

Components of the desired full system

Veterans can:

  • Register on the site
  • Input their profile/upload resume so employers can find them
  • Search for jobs
  • Register to attend career fairs
  • Respond to targeted ads from lead generation system
  • View and respond to franchise opportunities

Employee seekers can:

  • Post jobs ($)
  • Search candidate profile database ($)
  • Register as event exhibitor ($)
  • Buy other products & services ($)

Staff can:

  • View health of events to determine if we need to do extra marketing
  • Setup and monitor lead generation customers and ads
  • View charts & reports on key performance metrics
  • CRUD Markets Buzz Media Hits
  • Operate the email marketing system
  • Administer some of the public web content (some sort of CMS, don’t think they can just use git and the main code, maybe use Rit?)
  • Process orders (initial implementation is to just generate Unfuddle tickets via API)
  • View accounting data (we’re switching from Quickbooks offline to Quickbooks Online)
  • Use the CRM (we’re switching to insidesales.com)
  • CRUD documents in shared document repository (right now we use shared FTP system straight out of 1995)

Other:

  • Blog at domain.com/blog rather than blog.domain.com

Implementation strategy

  • Install RubyCAS which gives us flexibility to have each app standalone if needed

  • Apps will be written to depend on RubyCAS, we can extract/refactor later if needed

  • Rebuild veteran job board in Rails 2.3.5

    • Wire it into main site via Apache rewrite
    • Upgrade to Rails 3 when Rails 3 is ready for us
    • Later, refactor to a generic, open-source job board, with a proprietary veteran extension/engine (could then be mounted into master app)
  • Rebuild event management system in Rails 2.3.5 or 3 depending on when we get around to starting it

  • Smaller apps will be built as individual Rails 3 apps, mounted into a “master” rails app where appropriate to save on server resources and ease of deployment

Anyone else struggling with multi-rails app decisions?

I’d love to get feedback from people who are struggling with similar issues trying to break a monolithic legacy app into multiple smaller apps. So fire away!