One of my grandad’s best friends, Kovács János, was a talented chess player.
They used to play chess together every week. János consistently beat my grandpa,
but winning was not the focus of their play. It was a dedicated time to talk about...
When engineers want to introduce a change to the system, they use pull requests
to package the change and present it to the rest of the team. A pull request
usually contains a title, a description, and a list of commits that aim to
change...
With the microservice architecture style, services and their data are contained
within a single bounded context. This architectural decision helps us to develop
and deploy changes in one business unit fast and independent of other services...
Receiving a request, saving it into a database, and finally publishing a message
can be trickier than expected. A naive implementation can either lose messages
or, even worse, post incorrect messages.
Three days have passed since I completed my first half-marathon here in Novi
Sad. My legs are still sore, I still have several calluses on my feet, and my
butt muscles are still screaming when I stand up. It’s the perfect time to
reflect...
I was talking with a friend a while back. He’s a tech lead at
a local company. We were discussing our ongoing projects and
what is stopping us from completing them. He made an excellent observation:
Killing processes in a Unix-like system can be trickier than expected. Last
week I was debugging an odd issue related to job stopping on Semaphore.
More specifically, an issue related to the killing of a running process in a
job.
We made some major steps in software automation, more specifically release
automation. We coined the word DevOps and invented a culture that unites
developers and operations. We invented the term infrastructure as code that
represents our...
Mentoring younger developers is a very rewarding experience. It challenges your
your pre-established ways of thinking, and it forces you to re-evaluate your
long held principles. For example, a simple question like “Why does it matter
to...
Last week I was debugging a weird bug in one of our services. In the logs we
saw an SQL error “repetition-operator operand invalid”, so I was pretty sure
that we have a broken SQL comparison in one of our services. The weird part
was that this error happened only occasionally, seemingly randomly.
A year ago, I made a big decision — I decided to start working from home.
This decision had a significant impact on my personal and professional life. It
changed the way I approach people. It changed the way how I plan out my day.
Most importantly...
Last week we’ve investigated a way to achieve stable pagination
for our new API. I’ve learned some new techniques for handling
pagination, and dig deep into the downsides of standard —
offset based — pagination.
Recently I switched my ISP provider and with the change I’ve got
a new WiFi router. The download speed is incredible, 10x the compared
to my previous subscription, but the stability got worse.
Slow database queries harm your organization in many ways. They can damage the
reputation of otherwise great applications, make background processing painfully
slow, and drastically increase the cost of your infrastructure. As a seasoned
web developer, it is absolutely essential to learn about optimization strategies
for your data layer.
In concurrent systems where resources are locked, two or more processes can end
up in a state in which each process is waiting for the other one. This state is
called a deadlock. Deadlocks are an important issues that can happen in any
database and can be scary when you encounter them for the first time.
The most prominent feature of PostgreSQL is how it handles concurrency. Reads
never block writes, and writes never block reads. To achieve this, PostgreSQL
uses the Multi Version Concurrency Control (MVCC) model, an elegant solution for
a very hard problem. If you want to design highly concurrent applications, you
should really invest the time to understand the bits and bolts of this
mechanism.
Misunderstanding transaction isolation levels can lead to disgusting side
effects in your application. Debugging such issues can be more than painful. The
SQL standard defines four levels of transaction isolation. Each of these
isolation levels defines what happens if two concurrent processes try to read
data updated by other processes.
A regular select statement does not give you enough protection if you want to
query data and make a change in the database related to it. Other transactions
can update or delete the data you just queried. PostgreSQL offers additional
select statements that lock on read and provide an extra layer of safety.
PostgreSQL provides the means for creating locks with application defined
meaning. These locks are called Advisory Locks and are an ideal candidate for
concurrency control where the standard MVCC (multiversion concurrency control)
doesn’t fit the bill. Advisory Locks can be the perfect tool in your arsenal
when you need to control access to a shared resource in a distributed system.
Locking is an important topic in any kind of database. Without properly handling
locks, an application might not only be slow, it might also be wrong and behave
in some insane ways. Therefore, learning proper locking techniques is essential
for good performance and correctness of our applications.
Your monolith was slowing you down, and you have decided that it is time to
invest in a multiple service based approach. There were lot of new things to
learn, but finally, you are free to experiment with new technologies. Your
services can be developed & deployed independently. Life is good.
Your project and organization are getting bigger, and you start to notice that
your monolith is getting out of hand. Trying out new technologies is out of
question. You are stuck with the same language and platform from 5 years ago.
Microservices are here to save the day! You decide to expose an internal API,
and limit development of new features exclusively as microservices.
If you are a bit like me, you are naturally quite neurotic and experience
feelings such as anxiety, worry, fear, anger and frustration more often
than you should. Deep down, your rational self knows that these feelings
should not control your life. However, detaching from the ‘now’, zooming
out and focusing on the big picture is easier said than done.
I’ve used Linux as my primary operating system for well over ten years, yet I
still stumble upon things that are completely unknown to me. For example,
several days ago, I wanted to display a formated table in my terminal.
When I started writing articles for this blog, I only needed to open a text
editor, write something interesting and publish it. This in itself was already
hard enough. Expressing your own thoughts and feelings to the world is
frightening, yet the practice is very rewarding and eyeopening at the same time.
My Rails app used to be fast and snappy, and everything was working just fine
for several months. Then, slowly, as my product grew and users started to flock
in, web requests become slow and my database’s CPU usage started hitting the
roof...
Ruby and Rails are slow — this argument is often used to downplay the worth of
the language and the framework. This statement in itself is not false. Generally
speaking, Ruby is slower than its direct competitors such as Node.js and Python...
After weeks of planing, painful debugging sessions, and making sure that
everything is covered with tests, your feature branch turns green. You are
ready to merge into master and deploy to production. You hit the “Merge” button
on GitHub, open your CI service and watch how master turns green.
Automatically, deployment to production is triggered, and after several minutes
your new feature goes live.
Ruby is not the fastest language, nor is it the simplest language, but damn it,
it is definitely one of the most fun languages out there. For someone like me,
who enjoys programming maybe a bit too much, a language that puts little or no
limitations on the things I can tweak feels very natural and an obvious choice
when it comes to solving complex issues.
Every three months, I like to sit down, zoom out from daily issues, and
focus on the big picture. I like to write down the things I want to
achieve, and to find out what is really important to me. This three month
schedule is ideal, as it is not too long so that I lose focus, nor is it too
short for it to feel daunting and boring.
A good craftsman is known by his tools. He never uses the biggest hammer in
his shed to fix a little bump, neither does he use a duct tape to join together
the most fragile parts of his craft. For a good craftsman both a hammer and
a duct tape are vital elements of his toolbox. He has a good eye, and the
intuition to choose the most appropriate tool for every situation he faces.
Deploying your services packaged in lightweight Docker images has many practical
benefits. In a container, your service usually comes with all the dependencies
it needs to run, it’s isolated from the rest of the system, and deployment is...
This year I made a concious effort to improve many things in my life. I have
started to exercise regularly, improved my diet drastically, started to write a
journal, and to retrospect my life and goals on a regular basis. One of changes
that I am most proud of is my changed attitude toward books.
A lot of developers choose to avoid the often big, clumsy and complicated
IDEs in favor of the Linux command line. At first sight the command line
is inferior to the experience you get from a full blown IDE. However, the
beauty of the command line is just that. It is fast, simple, and by default
it comes with very small set of pre-installed features.
A Serious Man is probably one of my all
time favorite movies. The protagonist, a simple physics professor, with a
simple, happy life, is suddenly hit by a streak of miss fortunate events. His
wife leaves him, while he is forced out of his own house. He is blackmailed
at work.
Over the last fifteen years, SSH has become a standard tool for remote
management of Unix-like systems and many network devices. SSH stands for Secure
Shell, and is one of the ways to get a command line (shell) access on a remote
machine...
Rails is great, but often it is not the best tool for creating smaller
applications. For smaller size apps, especially those that are mainly focused
around pure JSON APIs, Sinatra is often a far better option. Unfortunately, the
majority...
It’s a shame that, almost since its creation, JavaScript had been considered
more of a quick hack than an actual programming language. Lacking the tools and
the community that other popular languages had, for a long time it was a
language...
Mocha is a testing library for Node.js, created to be a simple, extensible, and
fast testing suite. It’s used for unit and integration testing, and it’s a great
candidate for BDD (Behavior Driven Development).
This is how usually all our geeky adventures start out: A colleague walks up to my desk
and says: “I must show you something interesting!!!”. Last Friday this cool thing was
the wall command.
Several days ago a colleague and I wanted to check whether our caching system
contains all the files that we expect it to contain. We started by writing a
bash command that would list and compare the available files. It had
the following structure:
Let’s say you have two servers named gandalf and charmander, and a configuration
file config.xml that should be present on each server. Due to some human error
the files got different and your servers started to act weird. It would be nice
to compare them and find out what part of them is different.
Recently, I have become more of a “Ruby/Bash/Haskell” guy, but
JavaScript will always remain one of my favorite languages, and I
couldn’t be happier when I saw the new new upcoming ES6 standard.
I remember the first time I tried to use the shell.
It was weird that I had to type in things and not just
click around to get things done. But gradually I got
used to it, and after a while it became my primary way
to interact with my computer.
Many developers fail to realize that by using the basic Unix tools, you can find
on any server, you can find and collect valuable data from your logs. Often the
data you need can be found without using any external services, including but
not limited to service measurements.
Last time, I have demonstrated how we can put together simple filters
to show only the lines we are interested in. This time I will show
you how you can manipulate these lines and select only the parts you
really need.
Many developers fail to realize that using the basic Unix tools, you can find
on any server, you can find and collect valuable data from your logs. Often the
data you need can be found without using any external services, including but
not limited to service measurements.
Ruby is an excellent language offering us a simple and human friendly
interface, however for system administration or simple task automation the
shell is a much better alternative. Luckily, combining them is easy.
The majority of today’s development is oriented around the web or around desktop/mobile applications. For the average programmer it could even seem like there is no other programming area out there. However, there is actually a huge number of programs developed for cars, televisions, phones, and similar everyday technologies. This article is focused on a small fraction of those areas — sms messages.
I have been programming for a long time. Probably much longer than I want to admit. Yet, for a long time, there was something mysterious about the way I created my programs. Yes, I could write a lot of stuff in programming languages, but I had no idea how to create a programming language itself.
Not so long ago, while reading an article on hacker news, I came across a strange little programming puzzle that seemed silly and trivial. I was sure I could solve it in a matter of minutes if I just sit down and think about it a little. Yet, the problem haunted me for weeks, and in one moment I just had to sit down and solve it. And what can I say, it was really hard, way harder than I tough. Here are the rules of the challenge.
Unix systems are really smart when it comes to interpreting your application. Not only do they provide you with an excellent environment for development, but also let you specify the interpreter in you source file. As it turns out, this technique lets you write an application in any programming language without forcing your end users to know the details of your implementation. This article is about describing this simple technique.
Two years ago I thought I knew a lot about the Linux command line. Then I started digging deeper. Replaced Bash with Zsh, learned about jobs, started writing shell scripts, and even ditched Sublime text in favor of editing with command line Vim. Again I thought I know a lot about the Linux command line. Then I started digging deeper again…
Have you ever wanted to create an awesome command line application but was lost in the sea of options parsing? Well, if you did, and even if you didn’t, Thor is here to help you.
There are times when the only thing I want to create is a simple API. In the Ruby ecosystem the standard for creating something simple is Sinatra. But, there are a lot of things you miss in Sinatra that you have predefined in Rails. Sinatra let’s you define and include only the things you actually need. Maybe this is a good thing, maybe it is not.
Downloading a file, backing up your database, or installing a package for your system are all instances of long lived processes that we encounter daily. When such a process takes a long time to finish, it is always nice to give some kind of visual cue to the user.
In programming we like to reuse stuff. Data, variables, classes and even whole systems. We have a rule of thumb to only write code if it can not be found somewhere else. But sometimes the same thing can have a different meaning in a different context. So in order to reuse code but have a meaningful name in various contexts, we use aliases.
Here is a story of my typical work session in the shell. It starts by a wish to make the computer execute some of my commands. For example, I want to list all the files in the current directory. From prior knowledge I know that the ls command does exactly that, so I use it, and get the desired output. But I am out of luck, the current directory contains too many entries and I just can’t scroll so much up in the history.