Each of us at CompileDammit wants to learn Groovy / Grails (and other tech) for different reasons. However, I do not believe any of us are currently intend to rewrite any of our existing applications on a new platform. We all work on different projects, but one trait they generally share is: These applications have required man-years to complete. Like the rest of you, we’re not building blogs in 15 minutes; we have not laid down countless hours on ZOMG The Perfect ToDo App. We’ve birthed hundreds of thousands of lines of code; included dozens of external libraries (dependencies); integrated with numerous third party vendors; exposed APIs to internal and external collaborators. This most likely resonates with you because it’s not uncommon and you do it every day.
This leads me to wonder:
- given any one of the larger applications I contribute to (at work) every day, what would motivate me to rewrite it in another technology?
- What — specifically — are my risks in doing so?
- What questions must I ask to find and mitigate those risks?
- What are my “unknown unknowns” — the things I can’t even think to ask because I don’t know they’re gonna bite me in the biscuits down the road?
- What resources exist — books, consulting, in-house experience, etc — from project leads, developers, operations folk which can help guide me through this process?
- How do I minimize surprise?
Hat tip to Nick Giard, Pete Freitag, Adam Tuttle, Scott Stroz, and others for contributions and conversations.
Why Rewrite? A Short List
While I am interested in exploring motivations for a rewrite, that’s not this post’s focus. Let’s assume for the moment that we’re rewriting for some of the following reasons. “OldTech” is our current old-n-busted tech stack which we’re kicking to the curb in favor of the shiny New Hotness.
- Unacceptable performance not fixable on OldTech
- Platform consolidation
- Difficulty in finding best-of-breed OldTech expertise (read: we can’t hire the people we need)
- Difficulty in training new people on OldTech — young developers don’t want to learn old-n-busted as it’s unlikely to advance their careers, for example
- OldTech has stagnated; innovation is slow
- Becoming increasingly difficult to find OldTech libraries that solve our problems; end up recreating too many wheels
- OldTech’s tooling — IDE, monitoring, etc — is years behind competing stacks
- OldTech is pricey
- The “language” of the stack is joyless
- The community is waning and innovation has slowed — unsupported frameworks/libraries, etc.
- An unethical consultancy might use this opportunity to win new work from an existing client, thereby both padding the coffers and subsidizing a team’s learning
- We’re bored and want to do something different
And so forth. Note that I’m excluding anything involved in the nature of “The existing application” itself that might warrant a rewrite. This list focuses solely on switching platforms.
The Application Rewrite: A Thought Experiment
We’ve seen several high-profile rewrites in recent years. Twitter moved part of its infrastructure from Ruby/Rails to Scala; Yammer did the same from Java to Scala and then switched back. Even Facebook is supposedly considering running its existing PHP codebase on top of the JVM. Surely you can think of lesser-profile migrations. Still, the number will be relatively small, and the number of successful, on-time, as-planned migrations smaller yet.
I wanted to imagine myself in a position where I evaluated rewriting one of my existing applications (at work) in a different platform. To do so, I’m going to interview myself. Journo-Marc has a list of questions for Geek-Marc. Unfortunately, embarrassingly perhaps, this list is rather anemic. It’s a broad-strokes list, and the problem with rewrites is that you spend so much time on the things you failed to consider. Failures of imagination are common. The more questions Journo-Marc can ask which result in “I hadn’t thought of that”, the better.
The spirit of this interview is not to deter the migration from OldTech to NewTech; rather, the spirit is one of investigation. I intend no judgment. The goal of the interview is to minimize surprises, to shrink the ‘what haven’t we thought about?’ surface area.
- How do you find answers to questions in NewTech? Are the official docs enough, or do you frequently find yourself traipsing through the blog-o-sphere? Are answers to common questions more often a straight line or a meandering curve?
- Does NewTech prefer to run on one OS vs. another? For example, if we’re a Windows shop, will NewTech require us to outfit with Linux or Mac dev machines? How does this affect our QA / UAT / Staging environments?
- What is the core mission of our application? Building PDFs? Reporting? Data Collection? What tools / libraries have we built in support of that mission, and are we certain these libraries exist and tools can be rebuilt in NewTech?
- Is our rewrite akin to hanging a picture with a sledgehammer? Do we have a particularly slow part of the system which could be pulled out and rewritten, leaving the existing application untouched? Can we chip away and modularize, rather than rebuild the entire app?
- What are the parts of the code where all developers fear to tread? What code has big block comments with “DANGER!” and “HERE BE DRAGONS!” and “NOONE KNOWS HOW THE F**K THIS WORKS”? How will you contend with those in your rewrite?
- What parts of the code are legendary, heralded for their brilliance? Perhaps you’re consuming a 3GB XML file in under a minute on 1 Gee Bee of RAM. Maybe you’re processing 20 million messages per second. Maybe your app supports thousands of real-time socket connections to users around the world. How will you replicate those in NewTech?
- What data export features must you support? Excel? PDF? PowerPoint? Word? Does NewTech provide these, either out of the box or through libraries / plugins?
- If you search your Issue Tracker, or poll project managers and developers, what features from the application’s history took an unexpectedly long time to program? Why? How will you contend with that during the NewTech migration?
- What proprietary / db-dependent features are used, such as SQL Server “Hierarchy” or “Geography” datatypes which may or may not have equivalents in NewTech? How many queries rely on these? Does this have implications for your ORM, as well?
- How much existing documentation will now become irrelevant? Or mostly irrelevant? How committed are you to rewriting documentation?
- What code runs on a schedule — nightly jobs, etc? Look at all of that code, because it’s often neglected and a frequently overlooked source of surprise.
- If you have a core mission — you probably have one or several but not more than a handful — you’ve likely built up years worth of supporting libraries. You probably know the APIs by heart, though perhaps you’ve never had to maintain much of that code. Look at it. All of it. Tens of thousands of lines of “helper” code. How will you replicate that in NewTech?
- What is the testing story in NewTech? What testing frameworks exist? Are they actively supported?
- In NewTech, when I change any bit of code — a model, a view, a controller, a service, a resource, what must I do to see that change in the application? How much time exists between Ctrl+S (save) in my editor and F5 (refresh) in my Browser?
- If NewTech prides itself on its plugin architecture and many of the features you’ll need come in via community-supported plugins, does the plugin system have any kind of vetting, ratings, or other facility to enable you to evaluate them? How well are they supported? How well are they documented? How nicely do they play together? Do known conflicts exist: Plugin 1 and Plugin 2 can’t co-exist in the same app due to classloader conflicts, etc?
- Is this your first time writing a sizable application in NewTech?
After you’ve spent a few months in the discovery phase, answering the above questions and dozens of others, you’ll likely come to see your application as a collection of buckets. Those are your services. Parallel to your rewrite you’ll be working toward SOA experience via books, articles, presentations, sample apps, etc.
What is your plan for migrating to a new platform such that your new app is organized into a proper service-oriented architecture?
- What is your current build and deployment stack, from soup to nuts? Build scripts, continuous integration, automated deployment (pushing code, restarting apps / services, etc). How will you replicate, even improve, upon that with NewTech? NewTech probably has a preferred ops stack which differs significantly from your current one, particularly if your current stack is a hodgepodge of spit-and-duct-tape.
- What compliance, certification and accreditation, and other time-consuming hoops must you jump through to get a green light for production deployment? Does NewTech present any significant challenges, or advantages, with respect to compliance?
- What monitoring scripts / software do you currently use to measure site uptime, performance, etc? Will these apply to NewTech? Or must you investigate a new monitoring stack as well?
- Does NewTech present any significant disadvantages or advantages with respect to cloud-friendliness, both technologically and licensing?
- What web services or external APIs do we expose? Have we carefully looked at each one and assessed A) how we’ll rebuild them and B) how we’ll work with consumers to contend with URL changes, if any?
- Are third-party consumers of our APIs relying on features of OldTech which we can’t easily replicate with NewTech?
- What testing procedures do we have in place so that third-party consumers can test NewTech implementations in a sandbox? What will we do to ensure a clean cutover?
- With what payment / ordering / billing / manufacturing / warehouse / systems do we integrate? Does NewTech provide such integrations?
- What third-party libraries do we use in our application? All of them.
- What third-party libraries might not work in NewTech? Perhaps we’re using no-longer-supported crypto .dlls as database extensions. Perhaps we’re using 32 bit COM libraries that will not work on our 64 bit JVMs. This is particularly dangerous territory with long-running, “ancient” tech which keeps the lights on or pays the bills but which rarely sees a developer IDE day to day. You need to root these out aggressively.
- For every third-party library we use, what corresponding libraries exist, either native or as plugins, in NewTech?
- What functionality is provided natively in OldTech — websockets, Image manipulation, PDF form filling, whatever — which is specific to the platform and not just the language — These are most likely the reasons we pay for OldTech, by the way. What of those native features must we replicate in NewTech? These may not be third-party, but they are a dependency which must be managed.
- What third-party systems does our software consume? What is the data format? What is involved in rewriting all of our third-party consumption in NewTech?
- Aside from the official docs, where do you go for help? How responsive are the mailing lists? How friendly are the folks on IRC?
- Can you approximate the size of the community? Does it feel accepting and growing, or guarded and insular?
- What conferences, big and small, have been put on both nationally and regionally? Does the number, frequency, or size of the conferences lead you to any insight on the vibrancy of the community?
- Find the one or two primary conferences each year for NewTech. Look at the past list of speakers and topics. Is it the same speakers? Same topics? You’re looking for freshness here… do you see it?
- If you or your teammates are well-known in OldTech community, you very likely are capitalizing on that reputation. When you’re an unknown in NewTech, will your n00bness and lack of access hinder you?
- Do you ply on your OldTech community reputation with seniors in your company? Does absence of a reputation in NewTech affect you, perhaps politically, in your company?
- Find and follow some of the “big names” in NewTech on Twitter. Do you like these people?
Most (all?) of the above questions, and their implied sets of nested bullet points, lead to an examination of dependencies in a system. The degree to which we can identify them contributes to the success of the application rewrite. Consider unidentified dependencies as landmines, and invest considerable energy in ferreting them out. You will not find them all. You’ll blow off a few metaphorical legs. Know, though, that the success of your platform migration starts here. This is fundamentally a human problem and solution, not a technical one.
Your team, all of you — project managers, system analysts, testers, developers — are on the hook during discovery. By the end of your migration (if an ‘end’ really exists), your ability to sit in the same room with one another without entertaining violent thoughts hinges on how well you collaborate as you discover answers to the above questions and more.
I want to hear your questions, as well. Put yourself in this same situation, and try to fathom the matrix of decisions you’ll need to make, problems you’ll face, risks you’ll take, problems you’ll solve as you rewrite your application. Speak to me, via comments.