(Database) Transactions should be used modestly

An article, posted 3 months ago filed in database, sql, programming, ruby, performance & simplicity.

It is good practice to leave your database in a consistent state. There are different ways to do this. Foreign key constraints, indexes, typing of columns, are all strategies to keep your database in a consistent state. Transactions are another way providing you a tool to keep the database consistent: if one of the inserts or updates fail, your database will rollback to the state before the first in the series of inserts and updates within that transaction.

Some languages make it really simple to create a transaction. In Ruby on Rails it is simply opening a block:

User.transaction do
  ## ... all db operations are now in a transaction
end

But be cautious; transactions don't come for free: they lock the table or row, which is bad for performance. It can, by design, stop other processes from updating the same rows. And all this gets worse when transactions take longer, when for example they contain request to remote resources.

Hence, my approach to transact…

Continue reading...

Blog concept: Sketchy optimisations

An article, posted 9 months ago filed in activerecord, database, optimization, orm, performance, query, rails, software & sql.

Recently a colleague was showing me a concept he was working on. He drafted a change in a fight against so-called 1+n-queries (actually for some reason unknown to me they're called n+1 queries, but my head isn't able to process the problem with just one more query after n queries…); in software development using ORMs like active record it is quite easy to make a single database request objects that when a presented within a view trigger other queries for every object because it has a relationship. Round trips to databases are generally bad as they take time.

For his change, he introduced a new class that we could seemingly reuse, with a just another (a bad code-smell) declaration of relations between objects and whether these should be preloaded when retrieving the primary object. This was in response to indeed a quite bad part of our code that entailed returning objects with counts of selected associations, but instead of counting these in the database, the current code was a…

Continue reading...

Why I stopped inheriting from ruby’s core Array class

An article, posted more than 3 years ago filed in workbook, gem, rubygems, ruby, inheritance & performance.

Inheritance is considered bad practice for quite some time now (Gamma, Helm, Johnson & Vlissides, 1994). Little did I know when I started the ‘workbook’-project in 2012 (note that I don’t have a computer science background).

The main reason I wrote this workbook-gem was that I wanted the most predictable API for working with spreadsheet data (acting as arrays of arrays), not having to use a different API when reading XLSX or CSV files, nor when writing it.

After learning that inheritance is not always a good thing, I still often thought of a workbook as an array of arrays and hence an exception to the rule. But then I came accross a helpful post by Avdi Grimm: [Why you shouldn’t inherit from Ruby’s core classes (an…

Continue reading...

Browserondersteuning

An article, posted more than 3 years ago filed in browser, Edge, chrome, Firefox, support, mobile, Safari, complexity, quality & performance.

murb hanteert een browser support grading systeem (een idee dat ik ooit heb gekregen van Anselm Hanneman bij het lezen van How to define a browser support level matrix) voor browserondersteuning. We classificeren browsers met een A, B, C of D.

Klasse Omschrijving A Beste gebruikerservaring; alle features werken en weergave is duidelijk. B Alle features werken. Weergave niet altijd optimaal. C Basis functionaliteit werkt (in ieder geval rollen buiten controle (b.v. niet-admin functies)), maar geavanceerdere functies zijn niet altijd beschikbaar. Performance mogelijk niet optimaal. D Wordt niet ondersteund.

B2B projecten

Veelal kantoortoepassingen, complexe schermen, mobile support is een nice to have.

Klasse A Browsers:

  • Google Chrome op Desktop (laatste en op één na laatste versie)
  • Micros…

Continue reading...

Total cost of ownership valt niet te generaliseren

An article, posted more than 5 years ago filed in software, samsaffron, performance, ruby, windows, linux, macos & support.

Om de zoveel tijd komt de term weer terug: 'TCO'. Total Cost of Ownership. Hoeveel het allemaal bij elkaar kost. Het werd in het verleden ondermeer uit de kast gehaald door Microsoft om te waarschuwen voor de kosten die de conversie van naar opensource software met zich mee zouden brengen. Onder TCO wordt dan ook gekeken naar o.a. opleiding, de kosten van licenties, wat de onderhoudsmedewerkers kosten (linux beheerders zouden duurder zijn dan mensen met een microsoft diploma). Wat willekeurige observaties.

Jaren terug genoteerd:

> Grappig om te zien hoe hij met het bijna niets kostende stukje software (van een grote speler) vele uren bezig is om via de complexe interface iets relatiefs simpels voor elkaar te krijgen: een factuur te printen. Straks gaat het zich terugbetalen, zo gaat het argument… maar ik heb er weinig vertrouwen in. Niet in dit geval. Wanneer je werkt met relatief grote bedragen worden er niet zoveel facturen verstuurd. Automatische koppelingen met de bank is …

Continue reading...

Must do speed optimalizations on nginx

An article, posted more than 8 years ago filed in performance, nginx, server, configuration & cache.

Nginx's default configuration needs a bit of extra configuration (at least on Debian systems) to enable gzip and client side caching. Two very quick wins for better performing web-apps.

Enabling gzip for more content types

Compression makes files smaller. By default only HTML is gzipped, but it it makes sense for quite a list of other file types too. This, however, excludes(!) images, which have their own methods of compression: compression over compression delivers you nothing, and costs you and your end-user a few more CPU cycles.

So find the gzip on; line in /etc/nginx/nginx.conf file (make sure it is not turned off or commented), and either uncomment the gzip_types-line or use this, more complete, line (including svg):

gzip_types image/svg+xml text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

Client side caching

Every browser has a cache of its own, …

Continue reading...

Ruby on Rails is fast

An article, posted about 9 years ago filed in speed, performance, rails, cache, caching, ruby on rails & ruby.

Of course, this title is obviously too blunt. Still, when I see applications being developed on supposedly fast languages such as Java that perform terribly slow it makes me wonder.

Today I had to fix an issue with the slowness of an overview page inside a product I wrote using Rails. I don't like pagination (it's a workaround), but I wasn't expecting pages with over 700 items. The page with items stored in a traditional database was performing somewhat slow: it took about 6 seconds to load. The fix however took me less than half an hour (including searching the docs) from idea to execution and deployment on production (writing this post took me longer):

  old view code to render the item

Passing the item itself to the cache ensures that the cache gets invalidated when the item is updated. The page load it is still kinda heavy, with 500ms of load time, but this is acceptable for its size.

Features like this make Rails not only a super fast way to realise…

Continue reading...

murb blog