Ryan Kahn


Vault: Thinking Differently About Secrets

Vault is a service developed by the fine engineers at Hashicorp, which is designed to safely secure any data you want: passwords, SSL certificates, application tokens, etc. Aptly named, it can be sealed by any authorized user, but can only be unsealed with the use of n keys (3 by default), so in the event of a breach a single bad actor can’t gain access to the system.

Keep reading
Debugging Event-Driven Microservices

Debugging event-driven microservices can be a nightmare: logging is typically distributed across every service, and the event flow can’t easily be followed through code. This means debugging often involves going code-spelunking; mapping out every event that has been sent and following the chain. But this can yield complicated state diagrams with arrows crossing over themselves as you discover some events can call back up the chain — you can pull your hair out trying to keep all of it in your head.

The lesson here is that you can’t debug microservices in the same way you’d debug a monolith. But by appending some data to each event, you can start spotting issues more easily:

Keep reading
Common Promise Anti-Patterns and How to Avoid Them

Engineers making the move from callbacks to promises make common mistakes and introduce anti-patterns into their codebase. During my time working with promises at Runnable, I’ve identified a few common anti-patterns people use that cause issues maintaining the codebase. As I go through these anti-patterns I’ll explain what the pattern is, how to avoid it, and then take it a step further using Bluebird to make the code cleaner.

Keep reading
Finding the Root Cause of Elusive Frontend Errors

Frontend applications always have a multitude of user interactions and flows for how a user can get to a particular state. Sometimes these states are not intended and errors happen. Errors can be incredibly difficult to track down, so a reliable process for finding the root cause of an error can save a lot of time and confusion. Our process involves using a few services in conjunction.

Keep reading
Elastic Routing in Runnable

Our service gives teams full-stack environments for every branch. This means we run all repository branches simultaneously, each on a different container. As new commits are pushed to a branch, we automatically rebuild its code on a new container. To make all of this useful, we give a URL to each branch that’s always connected to the container with the latest commit. Behind the scenes, our routing system dynamically switches the container that’s connected to the branch URL, which may have ended up on a different host to help distribute load across the instances we provision for every team.

Keep reading
Feature Flag Routes Safely with Express Middleware

We had a new feature request come down the pipeline while we were testing Runnable with some of our early users — to allow teams to opt-in to our elastic URL routing behavior, as opposed to having it enabled by default. (We have a fairly complex URL routing system which would take its own blog post to explain. In short, it handles routing all user traffic to their respective Docker containers.) This system was one of the earlier services written when building out our infrastructure, and has gone through several bug fixes and tuning to get it working just right.

Keep reading
Preserving web terminals during connection hiccups

Sockets can be hard. Scaling out websockets can be even harder. At Runnable, we make use of websockets heavily — for notifying users that their containers are running, for implementing deployment messages, and for powering our terminals in the browser. Terminals are a tricky beast to tackle. I learned that a few weeks ago, when our users’ terminals were getting lost and reset based on uncontrollable network issues.

Keep reading