9 ms·
I had the experience of inheriting a codebase that was halfway through the process of being “strangled”, and it was a nightmare. The biggest reason being that i
by d_watt 7y ago
I had the experience of inheriting a codebase that was halfway through the process of being “strangled”, and it was a nightmare. The biggest reason being that it's not a "fail safe" way to plan a project. In this particular case, a full replacement was probably a 12 month affair, but due to poor execution and business needs, priorities shifted 6 months in. It was full of compromises. In some places, instead replacing an API completely, it would call into the old system, and the decorate the response with some extra info. Auth had to be duplicated in both layers. Debugging was awful.
While some of the issues could be chalked up to "not doing it right," at the core of it, the process of strangulation described in the article leaves the overall architecture in a much more confusing state for the lifetime of the project, and if you have to shift, you've created vastly more tech debt then you had with the original service, as you now have a distributed systems problem. Unless you can execute on it quickly, I think it's a very dangerous way to fix tech debt, avoiding fixing the core issues, and instead planning for a happy path where you can just replace everything.
If you absolutely think you need to quarantine the existing code, I'd recommend putting a dedicated proxy in place that routes either to the old service or the new service, and not mixing the proxy and the new code. That separation of concerns makes it much easier to debug, and vastly reduces the likelihood of creating a system of distributed spaghetti. What I’d really recommend, though, is understanding the core codebase that powers the business, and make iterative improvements there, rather than throwing it all out.
- james_s_tayler 7y agoSo if strangling is out and big-bang rewrites are out... What do we do?
- hinkley 7y agoProbably the same thing a doctor does when a patient ignores a pain and they have to tell them it's stage 4 cancer: Provide palliative care and your condolences. At some point you have to ask how the company let things get this bad, and what they've done concretely to avoid it happening again. And whether you really want to participate in the heroic levels of effort it's going to take to keep the patient alive in 4 years. Louis C.K has a joke about how his ankle was bothering him and the doctor told him, "Well, it does that now". That's it? "It does that now?!" Monologue monologue. The first time I laughed along with his joke. On subsequent viewings I said, "Hold on..." Louis is a seriously sedentary guy. He's been letting things go even more than I have, which is saying something. But I do exercise. If I get to pick the feat of strength, I could make the leaderboard. When I bunged up my hip I got PT, and I went, and I could do the exercises. I didn't do all of them though, so it still bugs me from time to time (also on the last day the PT did something to my good knee, which is still bothering me a year later). If I were in proper athlete shape, they might offer more, because my prognosis for recovery from something more aggressive would be high. Nobody is going to look at Louis, or listen to Louis, and offer that. Louis is not going to do any of that shit. He's just going to crack jokes about it, or about you... as is amply evidenced by that set. So yeah, your ankle does that now, sport. (BTW, my ankle is fucked up too, and I do the exercises he pantomimed. They do actually help quite a bit, which he would know if he had tried them even twice) And yet we do it at work all the time. And I am seriously beginning to wonder what would happen if we just triaged these situations and walked away from some of them. If we just let the saner competitor win.
- pontifier 7y agoI'm in the interesting position of having just walked into a situation where the paitent was already dead, and organs had already been harvested from the old company. Rightfully angry customers hadn't had access to the legacy system (it's costs killed the company) in several months. In the words of Monty Pyhon it was a dead parrot, and I came in to say "It's just resting... It's pining for the Fjords!" I'm almost a month in on a complete re-architect from scratch. Most customers are overjoyed that the business will be back soon, but I'm afraid their good will is going to be short lived if things aren't running soon.
- triangleman 7y agoIs there no way to resurrect the old system using the pattern described in the article?
- marktangotango 7y agoThis is a nice fantasy, but in practice, you walk away from one dumpster fire, and either 1. walk into a new one or 2. write another one. I've done both multiple time. It's inevitable really, when "legacy" means "code I didn't write" and especially with the evergreen groups of developers we have now (5 year "seniors"). It's amazing to me how otherwise competent, well intentioned teams can use best practices and still create balls of spaghetti.
- james_s_tayler 7y agoI'm beginning to think there are no best practices, only best executions.
- hinkley 7y ago'Best practices' is to developers as belly rubs are to alligators. There are a few of these phrases that seem to trigger some sort of docile reaction out of us. We should probably get that checked out.
- d_watt 7y agoIn my experience, most of the time the right decision for the business is investing the time into the core product. If you have 6 months (as stated in the article), what could you do with that time if you could dedicate it to improve the core codebase, rather than a rewrite? Worse case scenario is after 6 months you don't have a perfect codebase, but you've made it better, and you don't have yet another layer to deal with. Certainly, there are times where that's not reasonable. Maybe the core codebase is on a proprietary technology. Maybe it's built around an EoL framework. Maybe it's built on on a FOTM language that you can't hire for at all anymore. In those cases, which are more rare than developers like to admit, I think a piecemeal migration makes sense. In my experience, it's better to do it by altering the consumers. Whether it's a frontend that can point to another endpoint, or an API gateway that can switch out the service it's pointed to, or making a shim layer (proxy), that can serve that purpose. Having a service that is both the proxy and the new application is a poor separation of concerns, very difficult to reason about, and makes it too easy to intermingle the logic between the old and the new. In my experience.
- UncleMeat 7y agoThat’s not the worst case scenario. The worst case scenario is that the rebuilt system is worse and full of a bunch of new weird bugs. There is no guarantee that a rewrite ends up better.
- bdamm 7y agoYour guidance is true. However our industry is unfortunately also littered with well intended refactorings that resulted in any more bugs, feature changes, and customer impacts than the original developer intended, or even conceptualized as possible. So it matters a lot. For example, refactoring "to provide abstraction so future work is easier" is 90% of the time an error.
- cjfd 7y agoAt some point it starts to sound a bit like 'whatever you do, don't touch a keyboard'. Rewriting everything from scratch? Very risky, please don't. Strangling you old application? Some comments here tell us that we should not. Perhaps they are right. Refactor your current application? 90% of the time it is an error.
- eej71 7y agoWhat's wrong with constant ongoing evolution? Software is the ultimate metaphysical playdough. It can always be changed. Piece by piece. Step by step. Until it becomes something different. It's just... not exciting to do it that way.
- geekpowa 7y agoEvolution will not let you escape local minima, intrinsic/sprawling design decisions that cannot be evolved away from. I am sitting on a codebase whose oldest line of code is about 20+ years old and has evolved successfully in that time such that product it was 20 years ago and todays product are unrecognizable from one another. Its database schema is even older, encoding decisions made 30 years ago. Reasonable decisions at the time, but no longer reasonable. I am working on a major rewrite which will take a year. The nature of the changes required mean I cannot break it up into pieces and do it bit by bit as I have been for last couple of decades with major enhancements. A functioning product is all or nothing. As someone who is anti-rewrite, pro-evolve and accustomed to working on old codebases, and being my own business so its my own money on the line, the decision to embark on a 12 month rewrite is not taken lightly.
- james_s_tayler 7y agoCan you please do a blog post at the end of the project to let us know how it pans out as a case study?
- geekpowa 7y agoI think my original comment mischaracterized my project. It is a refactor, but a refactor that is going to take about a year to complete, where there will be nothing to show for it until it is finished. From old codebase, probably about 20% to 30% of it will be ripped out and replaced. Its not my first major project in terms of keeping this codebase capable. Previously written compilers/runtimes and IDE modules to keep it going : to gain control of codebase which was written in a commercial/proprietary dev environment into something I have full control over. That effort took a year. The difference in this case is I am deliberately, intentionally throwing code away, alot of it, for the first time and contrary to my instincts. Still a post mortem might be interesting. My successful efforts to code my way out of a proprietary dev environment was an interesting and risky project, discussed at length with relevant dev communities at the time, but probably worth writing up one day.
- mbesto 7y agoThere are basically two options: 1. Strangler pattern - which allows you to continually advance functionality, but will take longer and requires delicate care. 2. Complete rewrite - the only successful way to do this is to code freeze your legacy app. It's risky because it means keeping the product features stale for awhile, but less cumbersome to advance once it's done. Either way is risky. Choose your poison.
- dragonwriter 7y agoYou can do incremental rewrites without the Strangler Pattern; Strangler Pattern, is based on the idea that you cannot modify the old code (though, in practice, it often does involve modifications, as the old code often doesn't have the right architecture to implement even Strangler without some modifications.) When you accept that the old code is expensive but not actually impossible to modify, you can do an incremental rewrite without Strangler-style proxying, and not even needing to prioritize replacement of the user-facing components, and only or preferentially rewriting as necessary to make user-visible feature improvements or bug fixes, unlike Strangler Pattern’s preference for no-visible-effect initial replacements. (I call this “standard Ship of Theseus replacement”.) This typically is even better for continuing to deploy new features than Strangler, but does leave you with a system without a single clean boundary layer between new-style components (the replacement/proxy system in Strangler)) and legacy, instead you have a system with mixed islands of legacy and new components (possibly multiple styles of legacy, if a third set of standards is adopted before replacement completes.) So, again, it's has its own risks/costs, but it's a third option.
- mbesto 7y agoIncremental rewrites assume that your framework of choice is still supported. In my experience, I would say 75% of the time someone is considering a rewrite, it's because their framework of choice is out of date, which makes it impossible to modify old code.
- dragonwriter 7y ago> Incremental rewrites assume that your framework of choice is still supported You mean the one for the legacy? (Which I wouldn't call the framework of choice, since it's inherited, the new one is chosen...) Sure it requires that the legacy code is, at least internally, supported or at least supportable, and sometimes that's not the case. Though on larger production systems, letting them get to a completely unsupported state is rare, and those are the systems where the choice between big-banf rewrite, strangler, and a more free incremental replacement are most consequential, IMO. If nothing other than a big-banf rewrite is possible, there's not a choice, much less a consequential one.
- goto11 7y agoImprove the code gradually, module by module.
- bmichel 7y agohttps://medium.com/@herbcaudill/lessons-from-6-software-rewrite-stories-635e4c8f7c22 https://medium.com/@herbcaudill/lessons-from-6-software-rewr... suggests to build a new product without throwing away the legacy one.
- deleted 7y ago[deleted]
- ericmcer 7y agoI am in a similar position. We started the strangling process 2 years ago but due to management not wanting to disrupt old clients by shifting them to the new code (same stuff updated UI) the strangling strategy has basically shifted into us maintaining two copies of many feature. Success!
- felipellrocha 7y agoIf you're maintaining two copies of the same features, then, by definition, you're not exactly following the process described? The process was developed to avoid exactly that
- delusional 7y agoThat's the hardest part of any strangulation. The process can not involve any new features. If it does you will never transition everything.
- beaker52 7y agoThis is the case when you get involved in any mid-refactor system or codebase. It has to evolve to it's destination and it always happens over time bit-by-bit. Quitting in the middle of a murder isn't likely to give you the trunk full of insurance money, nor the pinacoladas on the beach living happily ever after with the victim. These projects, once started are best seen through, else you end up in a worse position than you started.
- d_watt 7y agoI agree, but to me that's why it's dangerous to think about refactoring the whole codebase at once, whether strangler or rewrite. Project design is just like software design, you need to be design it for failure scenarios, eg business priorities shifting, poor execution, etc, without leaving the overall situation in a worse state than when you found it. If you design a long lived code cleanup project where the only option is "we can't stop this project for another 6 months or we'll have an even bigger mess on our hands," that's poor project design. In this way, rewrites are almost safer. They're usually "atomic" and you can "roll back" by throwing it out if you can't focus on them. All this is based on dynamic business and product needs that are shifting every couple of quarters, and a technical team that's getting new people, and shifting off more experienced folks every couple years. That seems to be a pretty standard expectation to me, though I'll admit I'm mostly looking at this through the lens of early, mid, and late stage startups. It may be big companies that move slowly and can guarantee resources for a larger project for a long time are a different story.