Notes from upgrading Rails

Since Rails 5 was released a month ago, we took some time to upgrade to Rails 4.1.x to not be so far behind. Upgrading Rails is always a pain because it is connected to almost every bit of the application and you never know what will happen. Changes between 4.0.x and 4.1.x are documented and make for a good starting point, although, not everything is covered and there were three significant surprises. Read On →

When long queries are fast - an SQL optimization

As the amount of data Enectiva.cz handles grows, we need to find better ways to manage it. After auditing our database, we discovered a pattern which allowed us to reduce the amount of data stored by tens of percent. In order to take advantage of these potential savings, we had to change SQL queries used to access the data. This entailed a set of performance tests for various prototypical scenarios. One such scenario is: when was the consumption data last updated? Read On →

Postgres advisory locks

Postgres employs various types of locks to control shared access to data. Most often, Postgres takes care of using the correct lock on its own, but the API is public and application developers can leverage them as well. There is, however, one type of locks not used by Postgres itself: advisory locks. They are intended only for applications and Postgres does not enforce their use — it only provides functions to manipulate them and automatically cleans them up at the end of the session. Read On →

dotGo, microservices & simplicity

Recently, I watched all the recorded talks from last year’s (2015) dotGo conference as a way to learn something new about the language and where it is heading. You can watch 17 different talks on many aspects of the language, but there are two talks which stand out. The first one is Peter Bourgon’s talk about microservices and the tooling available for building them. Go is a backend language and often gets applied to the behind-the-scene processing which overlaps with a possible domain of microservices. Read On →

Including shared examples in RSpec

We’ve been using RSpec in testing of Enectiva since the beginning because of hwo expressive it is and how it helps us to structure test cases. One of the features which makes the later possible are shared contexts and shared examples. We use them quite often and, admittedly, there’re test files which take it to the extreme. However, there are valid use cases for both shared context and shared examples and it’s worth understanding them. Read On →

Postgres column tetris

Enectiva deals with non-trivial amounts of data on daily basis. That’s not uncommon in any way, in the grand scheme of things it’s still nothing. However, it’s in the region where you need to think about the data and can’t just slap it into the database without performance suffering. We are not Postgres experts but we take time and effort to learn about it so that we can leverage it efficient. Read On →

Tweaking Capistrano environment

Recently, we’ve been playing with our database setup in order to improve its resiliency. During the experimentation, we had multiple versions of the database compiled and running. To test everything, we temporarily needed to run db:migrate and related tasks against the new database. Our assumption was that it would be taken care of by changing the credentials for the database to the new instance. The migration runs just fine, but at the end, it dumps the schema to a file. Read On →

Duration in Go

We, lazy developers, like when we don’t have to type a lot and things just happen. Naturally, there’s a limit to how much should happen and finding this limit is often the hardest thing. Especially because it keeps moving. Ruby is very friendly in this way and takes care of many things for us, implicit type conversion among them. Go on the other hand requires more guidance from the programmer. Generally, it is a good thing, because it leads to more explicit and predictable code; however, the cost is verbosity. Read On →

Context modifying blocks

In Ruby code in general and in Rails code especially, there are situations when the global state needs to be modified. Yes, global state is bad and ugly but at the same time it’s ubiquitous and we have to deal with it. Apart from “permanent” changes, it is often necessary to change the state just for a moment, i.e. a function needs to run in a limited/altered context. A na├»ve approach (and the only one possible in some languages) of implementing this might look like: old_state = global_state global_state = :foo # do something global_state = old_state It’s easy to imagine the actual working code being longer, separating the matching operations which might in turn lead to an error later. Read On →

Hash and an array as a default value

Recently, I needed to schedule a set of operations over a fixed number of slots so that the number of operations in each slot is uniform-ish1. Because the number of slots was fixed, it made sense to initialize an array so that each item would have a default empty list of operations (thus avoiding the nil test when adding operations to slots). schedule = Array.new(number_of_slots) { [] } This worked nicely for a time, but later came in a requirement to split the operations into groups while keeping a single schedule optimizing the total number of operations in each slot regardless of the type. Read On →