Configurable implementation hidden behind a contract

Some concrete implementations are better to be hidden behind contracts, in a specific package. A layer of abstraction can save you later, mostly on unstable projects that often change requirements, or maybe you just want to test an idea, maybe you don’t have the necessary time to finish a task in a way you’d like to.

A good contract will save you. You can “throw” your implementation behind it and come back later to refine it. Sometimes later means in a few years. But if you’re behind a well designed contract, most probably you’re going to alter only the concrete implementation, without touching large areas of the projects.

I had to filter some user input. Some strings had to be HTML escaped, some sanitized to prevent different attacks. I’ve wrapped everything into a package, behind a contract. For escaping I’ve used Go’s html.EscapeString function, while for sanitizing I’ve found the bluemonday package, which is inspired by an OWASP sanitizier for Java. Continue reading Configurable implementation hidden behind a contract

Using channels to control flow

When I first met channels in Go, I thought they were just data containers. When you want to send data between routines, they are the go to. But later I saw they can be used to control an application flow, like waiting until something happens and only after that go on with the normal flow.

Here’s an approach to wait until some tasks have finished. Let me consider some input data that can come from anywhere: HTTP requests, files, sockets etc. That data can come in fast, but processing can take some time. If the application needs to exit (you restart it, stop it) but you want to wait until all the data you have in memory is processed, you can use channels.

First, I have a routine which processes input data read from a buffered channel. I simulate the slow processing with a sleep. Continue reading Using channels to control flow

Good behavior with bad consequences

Most companies emphasize on good behavior, being friendly to everybody in order to maintain respect and a calm working environment. Which is really great until they don’t speak up and avoid pointing out flaws.

We all have flaws. Not only things that we should improve, but pure flaws, things we don’t do the proper way. Things that we do wrong! And when you’re not told you’re wrong, you’re not going to improve. If you don’t improve, projects suffer.

Now imagine big companies with a lot of people who are not told what to improve, who are overly protected and bad things are hidden from them. Year after year. They have many directions they can’t level up in.

Being told you’re wrong shouldn’t be offensive to you, instead should raise a flag for yourself and make you ask questions, find answers, learn.

Converting seconds from float to int

Another small one on time precision that I’ve noticed.

package main

import (
	"fmt"
	"math"
	"time"
)

func main() {
	now := time.Now().Add(time.Hour)
	seconds = time.Now().Sub(now).Seconds()
	fmt.Println(int(seconds))
	fmt.Println(int(math.Floor(seconds)))
}

Line 12 will print -3599, line 13 will print -3600 (tested on Ubuntu). So watch out when converting the number of seconds to an integer, you might not always get what you need.

Time precision on Linux and Windows

Unit tests were needed on a new project I’m working on and a few weeks ago I wrote some. Last week, a colleague wrote some more, and when he ran all of them, mine were failing. Same code base, up to date, same tests. On my machine they were still passing. We jumped on the situation and saw math.Floor was giving a result on my machine, which runs on Ubuntu, and another one on his, on Windows.

The code is larger, but I’ve extracted and adapted what’s needed:

package main

import (
	"time"
	"math"
)

func main() {
	datetime := time.Now().Add(time.Hour * 24 * 7 * 4 * 12 * 3)
	seconds := -1 * int(time.Now().Sub(datetime).Seconds())
	a := 29030400
	x := float64(seconds)/float64(a)

	println("input:", x, "floor:", math.Floor(x))
}

Result on Ubuntu:

input: +3.000000e+000 floor: +2.000000e+000

Result on Windows:

input: +3.000000e+000 floor: +3.000000e+000

Continue reading Time precision on Linux and Windows

Language X is easy to switch to

I’ve heard “it’s easy to switch to a new language, it’s just a language, you just learn a new syntax”.

Well, I partially disagree. While you’ll may be able to learn the syntax fast, each language has its own particularities that you don’t just understand in a few days. Some languages have other best practices than others.

I believe that if you jump on writing code in a new language without understanding its philosophy, you’ll miss a lot of edge cases that will lead to undesired situations. Most probably no one will die, but time will be lost.

“We chose Node because we already had JavaScript developers, and it’s the same thing” – Yeah, server side optimization is the same thing. Same for concurrency. Or properly handling the file system.

“I took a look at Go and it’s trivial” – And a few months later you’ll end up tangled in your own work, refactoring each step.

While onboarding to the new project you have with that new language, I suggest  reading the docs, understanding the language’s best use, maybe right from the authors.

Letsencrypt wildcard SSL certificates

Since last year I’ve followed the announcements on Letsencrypt support for wildcard certificates. At the beginning of this year I was checking their website every few days, and just about a month after I took a break, here they are.

Read the official announcement and the technical details.

Waiting for Certbot to offer support.

Real benefits of SOLID principles

Those SOLID principles many talk about are really helpful. But why use solid principles, why is SOLID important? Because they were stated and tested by advanced programmers in real situations? I say this is an enforcement, a reason to trust them, but not the reason to jump on them. It’s actually about understanding the benefits of using them and being able to identify when you need them.

All of them help in the way of having clean code. But why would you need clean code? You can really have messy code which does the same thing as the clean one. Except when you aim for long term healthy business. Solid code makes solid business.

Each of the SOLID principles comes with its ideology, but does not guarantee a 100% benefit, because there could be other factors which more or less collide with them, the first one being when you play around the principles, but do not apply them properly.

While the benefits you get from these principles are well known, I’d like to state some of them which for me are more real, more close to the business side. Continue reading Real benefits of SOLID principles

“Obsessing About Best Practices”

Today I read a very good article about some mistakes that one can do as a programmer, and the only idea that made me a little bit uncomfortable was the one about best practices. The author was talking about “Obsessing About Best Practices”. While I agree obsessing is not healthy, I consider his statement “There are no best practices.” is too strong. I think it’s something that one could hear and get too confident about their decisions.

Thinking the things you know today are the best there can be is wrong. Trying to apply everything you’re hyped about is wrong. Giving the same 2 or 3 methods you know as solutions to any problem is wrong. Not being curios to find out what else exists beyond any best practice and beyond your knowledge is fatal.

Still, there are some general best practices that you should at least think of before writing code. There are those SOLID principles that some have no idea about, some guide themselves through them, and for sure some are not very happy about. And many design patterns which were tested for years and years. Again, I agree about not being obsessed with them, but try to understand where they can come in need. And stay up to date. The Singleton was a rock star some years ago, now it smells like a dead body in many misused cases.

Because “There are no best practices.”, projects can take on a really, really unwanted highway. I say they do exist. Just open your mind to see which are the proper ones for your case.

A fresh bug on Libvirt Python

If you’re using Libvirt Python library on Ubuntu, watch out for the 4.1.0 version. When trying to install, you’re gonna have this beauty:

Command "/usr/bin/python -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-6nHyGT/libvirt-python/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /tmp/pip-v9fxvX-record/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /tmp/pip-build-6nHyGT/libvirt-python/

It’a fresh known bug: https://bugs.launchpad.net/openstack-requirements/+bug/1753539

Until the patch is released, you can use an older stable version:

pip install libvirt-python==4.0.0