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? 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

 

Re: Isolation

It’s easy to talk about SOLID principles, design patterns, testing, moral expectations, self responsibility, and any other guide lines for a better world. Sometimes it’s even easy to adhere to those ideas, to put them in practice, no matter how may times some people repeat “there wasn’t/isn’t time”.

Although, there are situations that really stand against all best practices, like big legacy products which are already on the market, used by many clients, developed by many people who are managed very strict, in order to maintain… order. Or you need to get fast on the market.

The minimum that can be done is isolation. The least you can do is to throw your code in its own corner and use it only from there, then go back to change it whenever you want, without fear, with minimum cost and risk.

Handling API errors

The past days I’ve practiced Go by writing a package for Apixu weather service. They have a a straightforward REST service to offer their weather information.

Their service also returns an error response if it can’t offer data based on your needs, if you use an invalid API key, or for other cases. Of course, the Go package should also return errors if the case.

No problem with returning data, but I had some issues handling errors. There can be general errors that have nothing to do with Apixu (but with the package internals) and errors returned by them. My first approach was to return three values for each API method:

Search(q string) (Search, ApixuError, error)

But it smelled right away. There had to be another way. Continue reading Handling API errors

Reloading Go apps automatically while developing

There are some ways to automatically reload Go apps while developing, to not have to manually stop your app, build it, run it. Recently I ran into this article about a nice tool called Fresh.

I wanted to start using live reload (or hot reload) for a project of mine, but it had a particularity which gave me troubles when I tried Fresh. My case was:

  • I had a multiple apps Git repository
  • The apps were sharing some packages
  • If I edited app1 and the packages it used, I didn’t want both app1 and app2 to be restarted, only app1 (similar for app2)

Continue reading Reloading Go apps automatically while developing

My learning process

In the 7th grade I got my first PC. I’ve immediately embraced everything I could, I was curious about all the things. I’m talking about advanced, scientific things like changing the wallpaper, running the defragmenter, formating a partition, using music applications, installing games and software for friends, knowing what RAM, ROM, HDD and others are.

And in the 9th grade I had my first encounter with programming. It was Turbo Pascal. Then, I don’t remember why and how, I ran into the web world. First, it was HTML and CSS, which I wrote in Notepad, of course. Then started with PHP and MySQL, and probably in the same period I met JavaScript.

Along the years I peeked at Visual Fox Pro, C, C#, Python, Visual Basic, Java, and maybe other languages, too. Small stuff, nothing important. I was just curious.

I guess web programming was easier to get started with and that’s why I insisted on it. And I liked it. A lot. Continue reading My learning process

Counting number of items in a concurrent map

Lately I’ve been using Go’s concurrent map. And sometimes I needed to count the items I’ve stored in the map. I have ranged over the items and incremented a counter, and it was done:

package main

import (
       "sync"
       "log"
)

func main() {
       m := sync.Map{}
       
       m.Store("k1", "v1")
       m.Store("k2", "v2")
       
       count := 0
       m.Range(func(key, value interface{}) bool{
              count++
              return true
       })

       log.Println(count)
}

But I didn’t want to range over the items each time I wanted to count them. So I thought of incrementing the counter every time an element was added, and to decrementing it when one was removed. The following is just for practice, I didn’t perform any advanced tests. Continue reading Counting number of items in a concurrent map

Go HTTP server duplicate handler call

It took me a minute or two to figure out why, while doing some experiments, for the following built-in HTTP server use case, the handler was called two times, and so printing the log message two times.

package main

import (
       "log"
       "net/http"
)

func main() {
       http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
              log.Println("call")
       })

       http.ListenAndServe(":8800", nil)
}

The path “/” catches all requests, thus it catches the “/favicon.ico” request sent by the browser. So I’ve just used another path.