Multithreading without locks

Just because you’re sharing data structures between threads doesn’t mean you have to use locks.

Over the years I’ve come across a few approaches that help coordinate work between threads without having to make anyone wait. Here are a couple of them.

WARNING: I stopped using these patterns because they are easy to misunderstand and misuse, which can lead to random hard-to-diagnose bugs. If you use these patterns, you’re not helping the next develper understand the code better or avoid mistakes. You have been warned.


Newcomen atmospheric engine - an animation

A stylized animation of Newcomen engine that I made a while back.

Newcomen engine is one of the first viable steam engines originally made in 1712 in England to pump water out of mines.

Unlike later steam engines, it was an “atmospheric engine” in which the power stroke was produced by the steam condensing into water and thus creating a vacuum; the atmospheric pressure then pushed the cylinder down, moving the big beam.

It was extremely inefficient by modern standards, but that wasn’t a big deal if it was sitting next to a coal mine.


Making codebases age well

Why are some systems easy to update after a decade, while others are hard to understand after a year or two? And why are some companies drowning in bugs and need a month to complete a change that takes days in other companies?

Some of the root causes may be organizational, but technical choices also make a big difference.

After seeing plenty of projects on either end of the spectrum, here are the biggest differences between codebases that age well and the ones that don’t.


TDD is a lot easier with the right tools

I consider myself to be a pragmatic fan of test-driven development (TDD), writing maybe 30-50% of my code using the technique.

Having done it in four different tech stacks over the past few years, I look forward to TDD a lot more in some of them than in others.

Let’s compare a few of the experiences to see what they get right and what they don’t, from best to worst:

  1. .Net: xUnit and NCrunch
  2. JS/TS: Jest and VS Code Jest extension
  3. Python: pytest
  4. Java: IntelliJ and Infinitest


Kubernetes is useful, but it's not a complete platform

It’s been almost four months since we’ve migrated to AWS Elastic Kubernetes Service at HOOPP‘s 90-person Investment Solutions Group, and we’re starting to get a sense for what it’s like running on it.

While we ultimately liked it, right from the first interaction it became apparent that Kubernetes was not a complete platform, just a good backbone for a platform. If we wanted a group of 90 developers, business analysts, and product owners to work comfortably with it day-to-day, we needed to deal with configuration/operation complexities, platform quirks, and some gaps in tooling.


Books for technical leads and senior developers

These books help with the “lead” part: they help with things ranging from organizing better meetings to getting buy-in for a significant change. I assume most technical leads are already technically competent, so only one of these books could be called “technical”.

This is not the first list of books to be published on the topic. There are many others like it, but this one is mine. I found these books to be useful after I was first promoted to the Technical Lead role, and even more helpful when I tried to improve the rest of the organization around me.


How to select an API Gateway for (micro)services

TL;DR: Pick an API gateway that goes best with your tech stack, provided it meets the minimum feature/security/maturity threshold.

If you’re starting to implement the API Gateway pattern, in which a single gateway sits in front of a collection of services and routes the requests to them, you have a whole zoo of solutions to choose from.


Leveling up the team's communication habits

After working with various teams over the past years, I’ve noticed that a specific group of communication habits significantly help speed up the delivery. When the team members practice these, the delivery flows smoothly; otherwise, there are lags and misunderstandings along the way, and the work in progress builds up. This post presents only three of these habits; the overall framework is still only partly formed, and I’d like to have more discussions and testing before putting together something more concrete.


Why your service needs a client library

Specifically, I’m talking about the case of a back-end service that supports other back-end services within a single enterprise, e.g. in a microservice setup. To be fair, we can still get away with just exposing an HTTP endpoint or a queue where the client directly submits the message, but we can go a step further and make everyone’s life easier by providing a client library alongside the service.