found drama

get oblique

Category Archives: Code

Shell scripts, JavaScript pedantry, CSS fixations, Java debugging, and the rest of the polyglotism.

Conceptual Debt: sticking with your original-but-poor design (out of fear)

by !undefined

Conceptual Debt is Worse than Technical Debt:

This post practically reads like advocacy for UX Architects and (more broadly) Lean UX, or some similar approach of product design with built-in idea validation. A point that particularly resonated with me was the assertion around product inertia – this idea that if you get a product out in the market, there’s a tendency for it to stay the same – even if its initial design was poor – because of the danger of alienating the customers that did stick it out and learn the original-but-poor design.

“technical debt” as shorthand for five different scenarios

by !undefined

Towards an understanding of technical debt:

Particularly liked this blog post on technical debt, and mostly because the author is skeptical of the common thinking and conventional wisdom around the subject. The key takeaway is that when people talk about “technical debt”, they tend to conflate five different kinds of problems: 

  1. Maintenance work
  2. Features of the codebase that resist change
  3. Operability choices that resist change
  4. Code choices that “suck the will to live”
  5. Dependencies that resist upgrading

He invokes Norvig’s “all code is liability” here – which is pithy and memorable, but overstates the case – but ultimately his point is: technical debt is shorthand for one of these five scenarios where our complaints are ultimately rooted in the fact that we’re taking on the perceived burden of unpleasant work – usually due to some kind of implicit resistance or inertia of the codebase. (And this dovetails nicely with Simler’s “A Codebase is an Organism” post that made the rounds recently.)

From a practical perspective, the lesson seems to be: when you start invoking the phrase “technical debt”, try to consider which of the 5 categories the scenario fits into. What kind of resistance or inertia are you facing? And how can you move things forward without resorting to “technical bankruptcy” or “papering over” the problem with an Nth-level of indirection?

Rebecca Murphey on HTTP/2

by !undefined

Building for HTTP/2:

The venerable Rebecca Murphey on HTTP/2. The rise of HTTP/2 and what it means for building and deploying web applications (both on the front- and the back-end) is something that I’ve been curious about and following for the past couple years. As expected, Murphey’s take on the subject is thoughtful and thorough, with particular attention paid to what it means for “real world” developers. Something that she discusses in this piece which was not something I’d previously thought about was: whither the tooling for HTTP/2 applications? Her examination of the trade-offs and the “reality check” for the present day (and near-future) are also well worth the time.

“they don’t use a traditional UI”

by !undefined

No UI is the New UI:

A thought-provoking post, but let’s get our terms straight here. If SMS is or some other “simple messaging” is the primary interaction modality, then that is the UI–which is very different from something having “no UI”.

In my Medium response to this post, I mentioned that “even your smoke detector” has a UI, even if that UI is “just” a little light, a button, and some annoying-ass low-battery chirps at 3 o’clock in the goddamn morning.

The really interesting questions getting raised here are around what a user interface is, and how much of it can you take away. Can you shield people from the complexity of buttons and search boxes and hamburger menus? Can your app do its thing through a “chat” modality? Or is that going to be confusing? Can you lose the visual interface all together, a la Siri?

These are great questions to be asking, and I’ll admit that these are things that I’ve taken for granted.

canary releases and adaptive LIFO queues

by !undefined

Fail at Scale:

Great points by Facebook’s Ben Maurer, and an extremely interesting read about how they try to anticipate and manage failures. The observation that it’s so often linked back to configuration changes is an interesting one. I also enjoyed the bit about canary releases and the adaptive LIFO queues.

Being the Allspaw fan that I am, I always cringe a bit when I see someone so cavalierly throw out the phrases “human error” and “root cause” – no matter what their data say. But their “DERP” methodology softens the blow a bit. If you’re not doing post mortems incident reviews using something like that, then there’s a good chance that yours are toxic.

“entire classes of apps that don’t benefit”

by !undefined

Tradeoffs in server side and client side rendering:

A well-reasoned discussion about what trade-offs you’re making when choosing your frameworks, and whether to defer the majority of the view rendering to client, or to do it on the server. There are tons of posts out there like this, but this particular post is all signal and no noise. If you’re researching this topic, this is an excellent companion.

9 thoughts about 4 hours with AngularJS 2

by !undefined

Long story short: I was only able to give a couple hours of dev time to my hack team at our company’s hackathon yesterday. We chose AngularJS 2 as the backbone of our app’s front-end because… Well: why not take the developer preview for a test drive? Isn’t that what hackathons are for?

What follows is a short list of impressions. I haven’t meditated too deeply (or really at all) on any of these items. So here goes:

  1. “It’s just JavaScript.” This is something I said all along with AngularJS 1, but there seemed to be less ceremony here. For example, the service that we wrote? Literally “just a function”. No ng.factory() boilerplate whatsoever. Grade: A-
  2. TypeScript? OMG why? The docs are basically TypeScript by default. And I have no interest in TypeScript. (Not much interest in any of the compiles-to-JS languages, beyond that which is strictly academic.) I didn’t want to go learning (re-learning? refreshing?) TypeScript on top of diving into AngularJS 2. It’s frustrating that everything is framed this way. Grade: C
  3. Whither ES6? Given the state of ES6-to-ES5 compilers, it’s pretty disappointing that their “for JavaScript” docs are still ES5. I know I just said I wasn’t willing to throw TypeScript into the mix, but I would’ve added Babel. What’s more, the official AngularJS 2 docs don’t seem to mention ES6, and I wasn’t finding any decent blog posts or how-to guides in the quickie 10 minute search I did. (An eternity in hackathon time!) Grade: C
  4. Annotations? Sure, OK. I suppose I like the idea of the @View and @Component annotations, etc. (Maybe I’ve spent too much time with Spring in Java lately?) But they’re also restricted to TypeScript (vide supra) and the way that the translate into ES5 was a little… clunky? Seems like this is the price to pay for getting rid of some of ye olde AngluarJS 1 ceremony. Grade: B-
  5. Per-component bootstrapping. This one was confusing at first. Under AngularJS 1, you applied that ng-app directive somewhere in the mark-up (and pretty much only once) and the framework magically started up your app. Here, you define your components as directives (directives as components? either way: win!) and drop the associated mark-up into the DOM but… then what? The examples didn’t mention this but you’ve then got to explicitly call ng.bootstrap() on the function associated with that ~~directive~~ component. So once past the initial confusion of “why isn’t this working?” – it’s actually kind of refreshing, and promising because you can more easily build an app comprised of logically partitioned components. Grade: B+
  6. The docs reflect the framework status. I don’t know of a nicer way to put that point. Although some have accused me of being delusional, I always thought that the AngularJS 1 docs were pretty good. I think the AngularJS 2 docs could be good. They’re off to a decent start. But there are gaps. Unmentioned quirks. Unupdated sections. Inaccuracies. You can muddle through it, but it takes some persistence. Grade: C+
  7. All the low-level dependency injection. Unless I’m missing something (see my notes about the docs, vide supra) you need to do a whole bunch of annotation and configuration to get the dependency injection to work. Which is good because it removes a bunch of the Function.toString() magic that was much derided and the source of so much consternation. But in my main component, I had to set the bindings for the DI’ed service in two places (maybe only one of them was really necessary?) and then there was the realization that any services injected into the component’s constructor weren’t really reusable by functions attached to the prototype (so much for “just JavaScript”?) because “oh right that’s not how closures work”. (Side note: I’m sure there’s a good pattern for this, but not one that was obvious to me, and/or not one that I could figure out in 4 hours in the middle of the hack team’s noisy room.) Grade: C+
  8. Template locals. AngularJS 2 has this notion of variables that are local to the template. You can annotate a given element with #someHashPrefixedReference right in the mark-up. So say something like <input #foo /> gives you instant access to that input element as foo from within the template. Which is great for those places where you just need to capture user input off of some element without necessarily going through all the ceremony of adding it to the view model. There’s just one problem: #someHashPrefixedReference won’t work. Because it’s camelCase. So the mark-up makes it #somehashprefixedreference and so you need to reference it as somehashprefixedreference. Which doesn’t exist because it’s #someHashPrefixedReference. Or maybe it does? I tried a bunch of things, one after the other, all in rapid succession, because I had to head out. But: the point is the same: #somethingLikeThis didn’t work as I expected and #somethinglikethis did, which was not what I expected. But hey… local references. Grade: B-
  9. Package manager and/or module loader: don’t leave home without one. A bonus thought: I did not init this project with a package manager or a system loader – something like Browserify or webpack or SystemJS. I know better. And I know that I know better. But boy oh boy did I miss it once I realized I had started the project and didn’t have one. (I guess I’ve just been doing too much work lately on legacy projects that don’t have them?) Oh well, live and learn. Grade: N/A (this isn’t AngularJS’s fault… but they could maybe have more of an opinion about this in the docs)

Overall grade? C+ (B- if I’m feeling generous.) Overall I think they’ve reduced the surface area of the framework, and tried even harder to align it with vanilla JavaScript. But getting up and running isn’t as simple as I’d hoped, and briding the gap from AngularJS 1 seemed to put me at a disadvantage (re: unlearning things). The lean toward TypeScript also left me with a sour taste (again vis-à-vis the current state of ES6-to-ES5 compilers), and there are some rough edges in the state of the documentation. It’s definitely not out of the developer preview stage (not that anyone said it was). I remain optimistic that when it’s announced as production-ready, that it will be a great framework to work with. But for now… let’s check back again in 3-6 months.

[SIDE NOTE: A quick re-hash of my background to add some color/context around the above. I’ve been “doing” front-end development for about 15 years, and doing it professionally for over 7 years. I’ve been working with AngularJS since 2012 and have used it to build at least one large non-trivial application. I have given several talks about the framework, two of them public. I wouldn’t pretend to know everything about it, but I would say that I know enough that these comments are not unfounded.]

on SoundCloud’s microservices story

by !undefined

How we ended up with microservices.:

Fascinating story from Phil Calçado at SoundCloud about their shift from a monolithic Rails app toward microservices and a service-oriented architecture.

It’s refreshing to read someone else’s story, and to see how well it lines up with the one that I’ve been living professionally for the past couple of years. The best part? The sobering admission that no matter how disciplined you are about pulling things out of your monolith, that some things are just so stable and so… cheap (??), that you’re better off just leaving them in there.

Not that there’s anything wrong with the desire to keep decomposing, but only if it’s done thoughtfully. Because as a friend recently quipped:

If you have to deploy all your microservices together as a blob, they aren’t really microservices, are they? More like OOP in the large.

— Nick Husher (@TeslaNick)

September 30, 2015

eBay’s experience with Hystrix

by !undefined

Application Resiliency Using Netflix Hystrix:

Good write up from the eBay team about how they’re using Hystrix to put circuit breakers around problematic methods (read: “remote service calls”). Their experience seems to pretty closely match my own (though they’ve been using it longer, and at larger scale).

Also, let’s take a moment to sanity check that closing sentiment:

…but Hystrix has proven to be a sound and mature library for maintaining a resilient environment for our critical applications, providing high availability during any time period.

One thing to remember when working with circuit breakers in the context of a service-oriented architecture (i.e., micro-services) is that there’s the need to differentiate between being “available” and providing the desired level of functioning. Ask yourself, what’s worse: quickly getting back an error that you can handle? or waiting a (potentially) really long time for a successful response? Obviously there’s no one-size-fits-all answer to this question, as it depends on who your consumers are, what your SLAs are, etc. But it’s probably a good idea to get in the habit of preferring fast responses, coping well with errors and failures, and being the good citizen that doesn’t cause cascading failures because you’ve allowed all your request threads to back up and wait on long-running queries that maybe never complete.