Oct 4, 2019

It’s been quite the 1.5 months since Ira was born!

He’s growing big-big-biiiiiiiig and starting to become more alert which we’re all excited about. Samantha and I have fallen into a rhythm of longer sleep-shifts, which lets us get more continuous sleep. I take the 10pm-3am shift, and she gets the 3am-8am while I sleep before work. We’re obviously all a little exhausted but having a happy baby kinda makes it worth it!

Work is exhausting

In work news, we finally launched the new TFAW.com site. It’s built on Magento and it was a huuuuuge pain in the ass to get off the ground. Old TFAW was a hoary mess of bits strung together in a slowly decaying mass, but it was performant, was relatively shallow in terms of control flow, and had all the custom product-management tools that TFAW relies on to manage its massive catalog.

Magento, on the other hand, is extremely deep and complicated. Not only does it rely on extremely deep class-inheritance hierarchies, but many of the core features rely on generated code. Those familiar with wordpress might know that it uses a hook-based architectural pattern. You can register code to run associated with certain hooks, usually named like ‘before_this_thing_happens’ or ‘after_the_thing_completes’, where ‘thing’ refers to some action that makes those hooks available, such as posting a comment or publishing a post. Wordpress accomplishes this with what you might call co-operative plugin handling. Each action that wishes to publish hooks must explicitly call do_action('name_of_hook') at the times it’s appropriate, effectively passing control back to core wordpress code to allow plugins time to ahem plug in.

Magento, instead, uses ahead-of-time code generation to accomplish something similar. In essence, by writing a class FooPlugin with a method named beforeFoo or afterFoo or aroundFoo and writing a bit of XML, you can register FooPlugin as a plugin on any class that has a public method named foo . before... plugins allow you to modify the input parameters of the method before calling it (or initiating an early return before the original method is called!), after... plugins allow you to modify the return value of the method you’re plugging into before it is returned to the original caller, and around... plugins essentially allow you to do both, even replacing the functionality of the method in question if you never call the original method (passed as a parameter to your plugin).

This sounds really cool, and in a nerd way it kind of is. But in a “figure out why the code is broken this time” way it’s awful. Because, like wordpress, Magento has an extension marketplace that we came to rely on pretty heavily for some of the not-completely-custom-to-TFAW features, like Google product feeds, some enhancements to base Magento features, and so on. Imagine the havok that might be caused to the performance and reliability of your e-commerce site when you have 22+ extensions each plugging into deep Magento functionality, perhaps triggering multiple expensive actions for the simplest customer interaction.

Add more confusion and pain when you realize that most Magento extensions have extremely low code quality. Even extensions from large, reliable extension shops tend to be pretty awful, since those places tend to just buy the rights to extensions off of independents with minimal expertise and a gap they haven’t already filled.

Add even more confusion and pain when you realize that Magento has worked really, really hard to make certain that the situation on the backend is duplicated on the front end as well, with different extensions overriding core magento templates and plugging into or overriding core magento javascript (sometimes the same templates and/or the same javascript, leading to conflicts which must be sorted out by you sometimes very painfully, and most of the time in ways that are inherently fragile). Meaning that even a small update to an extension that has been working fine and is even of decent quality might suddenly break literally any portion of the site it touches due to an accidental conflict with one of the other plugins you have installed.

Add in more pain when the decision was made to use Magento-the-company’s hosted Magento service, which severely limits our ability to discover what was going wrong during development because of:

  • slow testing environments that fall over with even a fraction of the final product catalog due to memory issues
  • completely opaque deployment pipelines that fall over for mysterious reasons
  • read-only, extremely locked-down staging and production environments that prevent the diagnosis of problems that only occur in those environments (no debugging tools, no remote logging, etc.)
  • a really, really terrible local development environment experience. A big ball of extremely stateful scripts that have multiple steps and multiple layers of cache, and undocumented features just to build an over-complicated multi-container (8 at last count) docker setup that doesn’t even mimic how any of the other environments are laid out. Routinely, we’d have 1-2 developers completely out of commission for entire days or more trying to figure out why their environment had broken and, upon trying to start fresh, would no longer build. Sometimes the entire team would lose days after an update to the big-ball-of-scripts completely changed the precise ordering of incantations required to build the damn thing.

And upper management wonders why the project was 10 months late!

/salt /rant /work

Considering I just wrote about work approximately 10x more than I wrote about my own baby, here’s a picture, which is worth a 1,000 words:


That’s a cute baby right there.