oooops.dev

DevOps is hard

Serializing and de-serializing ES6 class instances recursively — September 30, 2022

Serializing and de-serializing ES6 class instances recursively

We have all been warned not to use ES6 classes. Perhaps by our colleagues, or perhaps by the endless amount of scary blog posts that show up if you dare Google the subject. However, if you thought you had a use case for them you might have used them anyway (or perhaps you are in too deep and cannot rewrite your entire codebase). And now you stumbled upon this serialization problem and need to quickly find a solution that isn’t “just use TypeScript instead”.

The gist of it is: JavaScript is not a typed language, although sometimes it is pretending to be. When we make use of type-y features like classes and interfaces, some behaviors might occur that are be a bit puzzling if you are coming from, say, Java or Kotlin. One such behavior is how class instances get converted to and from JSON.

Or rather, how they don’t.

Continue reading
QAing in production — August 12, 2022

QAing in production

In this article, I want to challenge where software testing happens and suggest that most manual verification (desk checks, QA, demo) that is part of a team’s delivery lifecycle should happen in production itself, rather than in some staging or UAT environment.

I have used this approach in several teams within medium to large organisations that were already implementing Continuous Delivery and/or Deployment, as it became the obvious and natural next step in our workflow.

Is it safe?

Let’s address the elephant in the room already: yes, performing your QA in production sounds like an oxymoron. After all, isn’t the purpose of QA to prevent broken features from being deployed to production in the first place?

This might have been true in the past. However, since then, a new practice has changed the way we release new features: Feature Toggles.

The basic idea is to have a configuration file that defines a bunch of toggles for various features you have pending. The running application then uses these toggles in order to decide whether or not to show the new feature.

Martin Fowler
Continue reading
Surviving Continuous Deployment in Distributed Systems — July 30, 2021

Surviving Continuous Deployment in Distributed Systems

Note: a shorter, summarised version of this article has been published on the Thoughtworks blog. Read the full article here or watch the talk delivered at XConf Europe:

Introduction

This is an article about the day to day of software development.

The industry seems to be at a point where a lot of us are using good practices such as Trunk Based Development and/or Continuous Deployment, or we are at least hassling our managers about it working towards it. I’m also a big fan.

But, as cool and shiny as these practices are, and as much as we reassure our fellow developers and stakeholders that they are completely safe, I believe they do present some risks.

Continue reading
An Isolated Developer Setup with Docker — May 15, 2021

An Isolated Developer Setup with Docker

In this post I am going to propose a set up to run any kind of application on a developer laptop in complete isolation. It is based on packaging the application into a Docker container, and convince it is still talking to the real world while we’re actually mocking everything around it (spoiler: using more Docker containers).


I have used this in projects of various sizes – from small scale to really chunky applications with lots of intricate dependencies – and has generally proven itself to be worth the initial investment.

In this guide I will assume that the reader is starting from scratch, with an application that is run locally just from their IDE, with no real automation or containerisation. Feel free to skip any of the steps if they are redundant or do not apply to your situation.
I will also assume the reader is familiar with basic concepts of Docker and networking.

Continue reading
How to attach a remote profiler to a JVM running in EC2 (and maybe Docker) — February 21, 2021

How to attach a remote profiler to a JVM running in EC2 (and maybe Docker)

Part of running big distributed systems at scale is encountering issues which are hard to debug. Memory leaks, sudden crashes, threads hanging… they might all manifest under extreme production conditions, but never in our laptops or test environments.

That’s why sometimes we might need to go straight to the source, and be able to profile a single JVM which is under real production load.

This guide aims to show how we can attach a profiler to a running application when the network, AWS permissions or even a layer of containerisation might be in the way.

We will achieve this by making use of a profiler agent running next to the remote JVM, which will send data to our profiler client. The two will be connected by an SSH tunnel.

Continue reading
Visualising distance from the main sequence and other Clean Architecture metrics in Java —

Visualising distance from the main sequence and other Clean Architecture metrics in Java

Image result for clean architecture zone of uselessness

I must not have been the only one to read “Clean Architecture” by Uncle Bob (Robert Martin) and be immediately sold on the abstractness, instability, coupling and main sequence metrics.
I must not have been the only one to immediately Google for tools to generate them for whichever codebase I happened to be working on at the moment, anxious to see if my refactoring instincts could be backed by a pretty diagram.
And yet, based on the very disappointing (lack of) results, it seems like that might be the case.

There are a few tools for the job yes, but they are clunky to run at best, and they definitely do not produce a visual output to quickly get insights from.

After hours of tinkering and getting a result, I thought I would share and write this guide for others like me who might have gone through the same experience. Hopefully it will spare some time to the next person.

Continue reading
See which process is occupying a port — February 14, 2021
Solving the Docker in Docker dilemma in your CI Pipeline —

Solving the Docker in Docker dilemma in your CI Pipeline

There are some tests (integration, end to end, component…) in most modern test suites that rely on some external resources in order to run. Confusing industry terminology aside, their goal is to test the integration between some part of our application and the outside world, like a database or a queue or even some other team’s application.

This is often accomplished by having a Docker container pretend to be the external entity we wish to mock – which is easy enough to set up in a developer’s laptop:

However, things get a bit more tricky once the same test setup has to be run in the team’s CI pipeline.

The reason being, a lot of modern CI/CD tools like Jenkins, GoCD etc. rely on their build agents being Docker containers themselves.

This presents developers who wish to run integration tests in their CI with the task of spawning Docker containers from within other Docker containers, which is not trivial as we are about to see.

Continue reading
The same code with Callbacks vs Promises vs Async/Await — February 13, 2021

The same code with Callbacks vs Promises vs Async/Await

Sometimes in JavaScript to have to deal with different flavours of asynchronous code, so it is handy to be able to map back and forth between them.

Callback

Functions that do something asynchronously are typically implemented using the callback pattern, and their implementation might look like this:

const myAsyncFunction = (parameter, callback) => {
    const result = //do something async here...
    callback(result, error);
};
Continue reading
SSH Multiplexing and Master Mode — January 31, 2021

SSH Multiplexing and Master Mode

When using SSH bastion hosts it is common to set up new connections for many of the use cases discussed in the previous section throughout the day.
Normally we would start a new TCP connection for each one of them. However, open TCP connection are a finite resource on any machine, and each one of them takes some time to set up.

Multiplexing is a feature provided by SSH which alleviates these problems. It allows a single TCP connection to carry multiple SSH sessions. The TCP connection will be established and kept alive for a specific period of time and new SSH sessions will be established over that connection.

It works by creating a “control socket” file which will be used every time we want start a new connection.

We need to pass two command line arguments in order to leverage this feature:

Continue reading