Cussing-free git commits

A few months ago I got a message from a random engineer on the company slack; he told me that he reviewed one of my pull request, and I might want to go through my code again, since I left some “inappropriate” debug logs there. I immediately checked what he could’ve mean, and I found the println() with a content that was unmistakably created out of sheer rage and desperation caused by hours of an unsuccessful bug hunting session. Unless you have a temper of a zen-master, I bet you know what kind of bug I’m talking about.

I prefer to prevent “accidents” like this one - after all, this is what agile is about, right? So I started to look for a solution - then ended up at git hooks pretty fast. However, with git hooks we have basically two options:

  • run the same pre-commit hook for every repository and skip the repo-defined hook (follow the red arrow)

or

  • copy my pre-commit hook to every repository I work, worked and ever will work with (go as the green arrow). Neither is a good choice. 😕

running-both-local-and-global-git-hooks

What I want instead is to run both, basically to go through the dashed arrow. And there is a fairly simple way to achieve this.

Read more

Messing around with Cloudflare workers

It has been two years since I tried moving Pajthy to AWS. Back then I left the project unfinished - I wasn’t able to find a solution for the websocket migration that I was satisfied with. Now I’ll try again; but this time instead of AWS, I give a shot to Cloudflare’s Workers.

With the latest serverless migration effort, the work to migrate the backend functionality was well organized into the following topics:

  • wrapping the business logic serving into a function
  • implementing a new storage layer, with data consistency in mind
  • deal with the real-time messaging

In this post we’ll investigate what options we have for these issues.

Read more

Simple End-to-end Testing with Lambda Functions

On the latest project I worked on we had regularly running end to end tests making sure our public APIs are up and available; it proved itself useful several times by catching bugs early that were not detected by the unit or integration tests - we even connected it to our alerting as well, to let it detect issues before our users do.

However, after doing that we realized that we are getting a lot of false positive alerts - not because the service had issues but the environment we used for running the tests were not designed for this purpose. The Jenkins instance we had was intended to be the tool for building and deploying services - best-effort availability, often overloaded - and thus not ideal for executing something on which we could rely on as a highly available sentinel watching over our service.

the current end to end test architecture with jenkins

In this post we will look for a better alternative for this setup.

Read more

PostgreSQL: Unique Constraint on Joined Tables

Recently I had to pay some tech debt for a piece of software that did not have it’s fair share of love in the past years: while it gets fresh features frequently the tests are quite neglected, thus refactoring takes an awful lot of time. Also, considering the state of the code and the level of over-engineering it suffered, our team already decided to split the service into smaller pieces in the near future - so the challenge is on: how to fix the issue with the least time invested, but with the current engineering best practices?

This is the entity relationship diagram of the related tables, simplified (and from a more common domain):

entity relationship diagram

Adding a single unique constraint to a postgres table is simple:

alter table
  vehicle
add constraint color_key unique (color);

Adding a composite unique constraint in postgresql is not difficult either:

alter table
  vehicle
add constraint color_make_key unique (color, make);

But we have three tables here: Vehicle has the attributes that are common and both Car and Truck have their own attributes. In our example there is a color attribute that is shared and we want to have a constraint that prevents same typed vehicles with the same color.

Read more

Working with DynamoDB

In the previous piece we redesigned the store interface for the backend in hope to have a better DynamoDB implementation to it. After the changes we have to provide a Load method that returns our Session object with the current version of it, and a Save method that will get the ID, the modified Session object and the (assumably) current version that matches the one we still have in the database; if the provided version does not match the current version, the method should return an ErrVersionMismatch error.

Originally I was planning to have the content of this post together with the previous one but while in the making I realized it was getting too long for a single post. On the flip side, now that the post was splitted in two, I have the chance to show some things in more details that I originally planned 🎉!

Read more

What is optimistic locking?

In the previous post we were wrapping our backend server into a lambda function. It is working just fine, but without a persistent storage layer there is no much worth to it; and the in-memory solution we have right now is everything but ideal for a serverless architecture.

The store interface we work with for the storage layer is a rather simple one:

  • there is a Load method, which returns the Session object from the database if it’s present, otherwise returns an error
  • and a Save, that inserts a Session with given ID

Couldn’t get any simpler, right?

man shrugs and says: ‘easy’

The in-memory implementation uses a simple map for storing and retrieving the data and it’s prefect for the job; so let’s give a try for AWS’s flagship, key-value database, the DynamoDB - which, if you strip away all the fancy features, is just a simple map after all…

In this post we take a look on how optimistic locking is different from the usual, pre-locking approach and prepare the store interface for optimistic locking. In the next post we’ll have the DynamoDB implementation of this store that is using optimistic locking.

Read more

Wrap a REST Service in Lambda

At a first glance it might sound controversial that I want to wrap a REST server - a typically long-running process - into a serverless function. I’m sure this trick won’t work with any services; in our case luckily there are some aspects of the pajthy backend that make this possible:

  • the web server is included in the executable (for an excluded example think about standalon tomcat instance with a .war package)
  • minimal ramp-up time before able to serve an incoming request (again, just compare your minimal java webapp startup time with a golang app with the same functionality).

Also there is an extra surprise in go’s standard library that comes handy, more on that later, I don’t want to spoil the fun! 😉

Read more

Moving an SPA to S3

This time will walk you through how I moved the pajthy frontend - a single page site written in react and packed on top of an NGINX server in a docker container - into AWS.

SPA stands for Single Page Application; it’s a setup when all the assets that are in the application’s domain are loaded with the first request. It has the same purpose as why some games have loading screens: it will reduce the time of content loading during in-app.

The pajthy frontend is an SPA, just a collection of static assets. Also since CORS headers are set up properly in an “allow all for everybody” way it does not matter where the site is hosted; if it can be downloaded it can be used as well.

Saying that, the plan was to set up a new domain for pajthy (up until now it was using a subdomain for akarasz.me), have some of the signature AWS service, S3 (short for Simple Storage Service 💥), upload the artifacts and that’s it, we have lift-off!

Read more

Intermezzo: why have I choose serverless?

Since I was a tad over-excited while drafting out the previous post, I had to split it: it would’ve been just too much for one. Instead I tried to separate the two posts so the first one starts explaining what this is all about while the second (this) one goes a bit more into describing things you probably already familiar with:

  1. what I mean when I’m talking about “cloud”
  2. comparsion of the basic building blocks for computing

and one that’s not that obvious: why did I moved from one cloud to another.

Read more

How did I go serverless

Serverless architecture is a recent interest of mine; in the last couple of weeks I was involved in a new project at work that’s running entirely in the AWS cloud. Since my most hands-on experience with the cloud so far was having a few virtual machines at Digital Ocean, I figured it’s best if I start exploring the Amazon Web Services at the beginning: with the ramp-up guide for the entry-level AWS certification, “Cloud Practicioner”.

Needless to say my motivation for finishing the entire course was dropping fast, but it was just enough for me to read through the (currently) 72 pages of “Overview of AWS” whitepaper listing all the available AWS services with a short (and very useful 🙄) marketing pitch. While reading the guide I realized, that the “lambda” service I heard about first a few years ago (and that time after a quick research I classified it as “useless”) is actually a quite interesting and useful tool when combined with additional services in the portfolio.

amazed
So shiny!

So what should one do after reading a few pages about something new and shiny? Tries it out in practice!

Read more