Rails.root.join speed vs regular string

September 12, 2019 Link to post  Permalink

A question came up today because of a Rubocop rule.  We have enabled the Rails/FilePath rule by default, and this warns about code that builds file paths in a string, and suggests you use Rails.root.join("dir1", "dir2", "file") instead.

This rule can be useful for code that is likely to be used on many different platforms, as it ensures that the correct path separator for the current platform is used to build the path.  However, many apps will never be used on significantly different platforms, so this rule has a cost without a benefit for many users.

Paraphrasing many tweets to @tenderlove - But at what cost?

Benchmarking Pathname.join and String Interpolation

The Rails.root object is an instance of Ruby's built-in Pathname class.  So I'll be testing this directly.  String Interpolation is built into Ruby and looks like "#{foo}".  

Here's the two lines of code I'm testing:

Finding the Trix.config object with Rails 6 Webpacker

September 2, 2019 Link to post  Permalink

Since I've upgraded this blog software to Rails 6, I wanted to also integrate the new ActionText component with the Trix editor to allow me to write new posts.  The integration is easy to get configured and working.  Since I only use the component in Admin mode, I created a new admin.js webpack and added these lines:

require("trix")
require("@rails/actiontext")

However, Trix has a default setting for Headings that sets the enclosing tag to H1, which doesn't work for my blog.  On the index pages, I display the post titles as H2 and on the post page itself, I use H1 for the post title.  If the headings inside the post are also H1 tags, then Google is likely to be upset, and it's harder to style them differently.

So how could I change the default behavior in Trix?

Browsing the Trix source code for configuration

The performance of FizzBuzz in Ruby

August 28, 2019 Link to post  Permalink

I recently came across this post on Dev.to where the author implements the simple Fizz Buzz algorithm in 5 different languages, including Ruby. What caught my eye was that the implementations were slightly different between the languages, and not just because the language forced them to be. With my performance spectacles on, I wondered how the differences in implementation might affect the speed of the algorithm if implemented in the same language.

Now, Fizz Buzz is used as a simple recruiting test to filter out people who can’t program, and all of these implementations will get you past that bar, and none of them should cause you to fail the interview process. Although the case version might confuse your interviewer as it’s a really unusual use of that feature.

But it is interesting to see something that isn’t complicated implemented in different ways to see the relative speed of a technique. Even the slowest here is actually very fast, but the difference between the very fastest and slowest implementations may be useful to know when you’re building code that needs to be performant in the future.

Upgrading the blog to Rails 6

August 11, 2019 Link to post  Permalink

Multi Thread Image After a short delay, I’ve upgraded the software for this blog and am planning on getting back into blogging regularly.

How long have I been away? Well, upgrading from Rails 3 to Rails 6 is not something I recommend in a single step. Since this blog is actually a very simple Rails app, it was easier to create a new Rails application and move the relevant code into the new app than it was to try to upgrade the code in-place. Missing 2 major versions of Rails is quite a gap.

At the same time as upgrading, I wanted to simplify the template and remove as much cruft as possible, but not go as far as using a static site generator. I’m using the Pure CSS system, with some minor customizing for my own content. This code also uses Turbolinks to reduce time between pages.

Make Sure Your Sitemap is using Production Data

I’m building a site, and have added the sitemap to help the Googles find the pages and give them an idea when the pages need to be rescanned. I use the excellent sitemap_generator gem, and it works really well.

My typical workflow during development is to run the sitemap generator on my development machine, with the Sitemap host set to the production server, and then to check the generated file in and push to the production server.

This works great to get something up and running, but very quickly your production server data will not match your development server data, particularly where the updated_at values are used, and this technique starts to break down.

The next step can be to run your code locally, but connect to the Production database to get the correct data. In the latest Rails versions - 4.1 and above - the database.yml file can include a URL to the database server. This makes it easy to configure your production database locally to allow this task to run.

Make Your Rails Application Multi-Threaded on Heroku

Multi Thread Image I recently read a pretty good e-book on parallel and concurrent programming in Ruby Working with Ruby Threads by Jesse Storimer. I decided to try out running something with Rails and threading enabled, so I converted this blog to run with Puma and Rubinius on Heroku. Here’s how I did that

Add Puma to the Gemfile and disable Unicorn

Also change the Heroku Procfile to use Puma with a minimum of 5 threads and a maximum of 16 - the defaults are 0 and 16

Update the Gemfile to tell Heroku to use Rubinius:

PostgreSQL 9.2 Range Columns and Rails 4

Pushpin Map of USA I recently had an application where I needed to find the location for an incoming IP address. I used the MaxMind GeoLite City database to provide the raw data, and I wanted this data inside my own database so I could link to the data records as needed.

The GeoLite data has two tables, the Location data that has the City, Latitude and Longitude, and a Blocks table that has a start/end IP address and a location_id from the Location table.

My initial migration looked like this, with a start_ip and end_ip as a bigint (to avoid problems with signed/unsigned conversions):

This worked well enough to find a location based on IP address, but on my MacBook Pro with PostgreSQL, with 1M block records, each lookup was taking over 230ms.

Building A Startup The Easy Way

Eliza Brock's MicroConf Coffee Mug Last week, I spent a few days at MicroConf in Las Vegas. There have been a small number of blog posts about how useful this conference is, and Christoph has a very good set of posts summarizing each of the MicroConf speakers

This was my second year, and I would recommend you all skip it next year to give me a better chance of getting a ticket!

A lot of directly actionable items came out of the conference, and Rob Walling asked at the start to make sure we all came away with at least 3 - this is a great way to ensure your customers get value: ask them to look for it as they go, so they don’t get to the end and go ‘ummmm’.

Caching External Service API Calls

February 4, 2013 Link to post  Permalink

In a recent project, there was an API call to an external service to retrieve some data. The code was written in the easiest way possible, which is to make the service call when the data is needed. For this application, the data is needed to populate a drop-down in a form, so the user is waiting for this call to complete before they can see the page they requested.

This particular service takes at least 1 second, and usually 1.5 seconds to return the data needed. Every single time the user visits this page. This clearly needs to change.

If you have service calls where the parameters to the call are likely to be re-used, and the results for a given combination of parameters is the same, then you can easily cache the service results and re-use them across requests.

In my project, the service call was performed inside a Rails view helper method during rendering of the content. The easiest way to cache this call is to use the Rails fragment cache view helper to avoid the call:

Caching Rails Objects in Memcache and the cache_lookup gem

January 31, 2013 Link to post  Permalink

Ruby on Rails has the ability to easily save the results of expensive operations to memcache for later use without the overhead of that expensive operation. Some things are easier to cache than others, and today I’m going to talk about one of the easiest things to cache in a Rails application - a single object, typically for a show action.

The Rails documentation lists all the different cache stores that can be used in your application. For any non-trivial application, one that will run on more than a single web server, then you’ll need to use something like memcache to store your data and share it between servers.

The current best way of accessing a memcache store is the Dalli gem. This will be the default store in Rails 4

Here’s my dalli configuration from production.rb for this blog on Heroku