One of the Hard Things

There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors.

I love that quote, not only because it's more amusing than it should be, but because it's extremely true. I know because I've been bitten by all three things plenty of times. Tonight it was while using the rails-settings-cached gem to handle some global settings for a Rails application.

At some point I truncated the settings table so I could reset it with new defaults. Afterwards my new settings weren't taking in the application or showing up in the database. I tried to mimic the behavior of #save_default but with some extra output by doing the following inside my initializer

if Setting.application_title.nil?
  puts 'Setting application_title.'

  Setting.application_title = 'My Application'
end

just to make sure something weird wasn't going on.

Setting.application_title wasn't returning nil so the setting wasn't being set, even after restarting the server. I discovered that when I added Rails.cache.delete('settings:application_title') before the above that it worked just fine. So of course the normal call to #save_default worked just fine as well.

It then occurred to me that the problem might be related to Spring which keeps Rails loaded and ready to get started quickly. I couldn't find confirmation in the Spring source but I'm guessing that by keeping the Rails process around it also keeps the cache nice and full. This means that, despite removing the setting's table's contents and restarting the server, the old settings were hanging around in memory. I'm hesitant to say with 100% confidence that this is what was happening, but it certainly makes sense to me.

Spring ships with Rails 4.1 by default so if you're making heavy use of the Rails cache this sort of thing is probably something you'll have to look out for. Also, keep in mind that the Spring readme does mention, "There's no need to 'shut down' spring. This will happen automatically when you close your terminal."