You are here: Blogsphere Longtail
Keep up to date with your favourite Rails bloggers in context.
El sitio web de Innofisio ya está instalado y listo!
Suerte!
Rails.cache rocks, but it can be tricky to set it up for development mode. For my purposes I need to:
The first thing I did was check out the excellent railscast and I read through the blog posts mentioned there. However, I couldn’t quite figure out how to get things to work – I kept getting strange errors where all of the methods were being stripped from my classes, rails was complaining that my classes didn’t exist or I was getting dreadful “singleton can’t be dumped” errors. After a lot of googling and experimentation, here is what finally worked for me:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# config/environments/development.rb config.action_controller.perform_caching = false config.cache_classes = false config.cache_store = :mem_cache_store, '127.0.0.1:11211', {:namespace => "dev"} # config/environments/dev_with_caching.rb config.action_controller.perform_caching = true config.cache_classes = true config.cache_store = :mem_cache_store, '127.0.0.1:11211', {:namespace => "dev_with_caching"} # config/environments/production.rb config.action_controller.perform_caching = true config.cache_classes = true config.cache_store = :mem_cache_store, '127.0.0.1:11211', {:namespace => "production"} |
Here are a few interesting points:
If you run your app locally without memcached installed, or without memcached running, you will see entries like this in your log
MemCacheError (No connection to server): No connection to server
Cache miss: Post.all ({:force=>false})
However, your app will work just fine. Rails will always execute the contents of the fetch blocks, and will return nil for any reads.
To run memcached locally, you need to install memcached. I develop on a mac and manage packages with macports, so for me it was as easy as:
sudo port install memcached
Once memcached is installed, you can start it with
memcached -m 500 -l 127.0.0.1 -p 11211 -vv
which will print verbose logging to STDERR, or you can start it as a daemon like so:
memcached -m 500 -l 127.0.0.1 -p 11211 -d
Either of these will start a memcached process running on port 11211, and it will allocate 500MB RAM (most apps can get by with 128MB, or so I’ve heard).
Once this is running, though, you need to set config.cache_classes to true – otherwise you’re app will blow up.
Rails.cache calls Marshal.dump on any object you try to put in the cache. Marshal won’t work on everything though – and you may need to write your own serialization script. I’ve had problems with classes that have lots of module_eval statements that create methods dynamically and similar meta-programming techniques. If you start getting errors like “singleton can’t be dumped”, check to see if you have any meta-programming going on. I’ve also had issues with REXML objects.
If you do have an issue with a class that Rails won’t cache, you can easily bypass the built-in serialization by writing your own _dump and _load methods. See the ruby docs for more info.
I have a new environment named dev_with_caching that I use to test caching locally. I set up my database.yml file so that it points to the development database, but performs caching and in all other respects mirrors the production environment. To test locally with that environment, I use:
script/server -e dev_with_caching -p 3001
I mostly use Rails.cache to cache data – and mostly for arrays of objects – like Category.all. As such, it’s to keep all of this in the model, but cache invalidation can be trickly to manage. Here’s a pattern I’ve started to use a lot:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
class Category < ActiveRecord::Base after_save :reset_cache after_destroy :reset_cache def reset_cache self.class.reset_cache end class << self def reset_cache cached_all(true) end def cached_all(force = false) Rails.cache.fetch("Category.all", :force => force) do Category.find(:all, :conditions => {:active=>true}, :order=>'position') end end end end |
Here’s what’s happening:
The first time you call Category.cached_all it looks for the “Category.all” item in the cache. If it’s not there, it executes the contents of the block, and adds it to the cache. When you save or destroy a record the cache is invalidated.
If you want to force a refresh of the cache, just specify Category.cached_all(true) and it will be reloaded from the database. Once this is in place, it’s easy to write cache invalidation scripts that both clear the cache and reload it at the same time.
I’ve done this by adding a class method that reloads the data, which is triggered by after_save and after_destroy callbacks. I’m sure there are a number of plugins that will do all that and more, but for my purposes this simple pattern works for me most of the time.
Finally, if you want to clear the cache at specified intervals you can do so easily with rake and cron. First, create a rake task that calls the model’s reset_cache method – since I normally have several classes with caching behavior I normally create a loop like so:
1 2 3 4 5 6 7 8 9 10 |
namespace :cache do namespace :reset do %w{Category Forum Post}.each do |klass| desc "Clear the #{klass} cache" task klass.underscore.gsub("/","_").pluralize => :environment do klass.constantize.reset_cache end end end end |
Now you can run
rake cache:reset:categoriesand your Category.reset_cache method will be called. To make this work with cron, you’ll need a slightly different syntax. The following command is suitable to execute from a cron script, or manually from the command line:
RAILS_ENV=production rake -f /var/www/apps/yourapp/current/Rakefile cache:reset:categories
It might take a little while to grok Rails.cache – but once you do your apps will be faster and you’ll quickly become a wild caching fiend!
Fair Copyright - Calgary Chapter (Photo)
Kempton interviewed by CBC radio (Photo)
The fuzz (Photo)
Bill C61 - Anti-competitive (Photo)
I recently discovered how easy it is to view my local development websites on multiple OS’s using VMWare. I use this primarily to see how awful my apps look in IE. Here’s how you can do it too:
When you installed VMWare, it configured all of the necessary IP addresses for you. To find out what they are, open Terminal and type:
ifconfig
You’ll see something like:
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1
inet 127.0.0.1 netmask 0xff000000
inet6 ::1 prefixlen 128
inet6 fdd3:5091:e6df:4c3d:21b:63ff:feab:d72e prefixlen 128
gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280
stf0: flags=0<> mtu 1280
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether 00:1b:63:ab:d7:2e
media: autoselect status: inactive
supported media: autoselect 10baseT/UTP <half-duplex> 10baseT/UTP <full-duplex> 10baseT/UTP <full-duplex,hw-loopback> 10baseT/UTP <full-duplex,flow-control> 100baseTX <half-duplex> 100baseTX <full-duplex> 100baseTX <full-duplex,hw-loopback> 100baseTX <full-duplex,flow-control> 1000baseT <full-duplex> 1000baseT <full-duplex,hw-loopback> 1000baseT <full-duplex,flow-control> none
en1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
inet6 fe80::21c:b3ff:fe7c:916e%en1 prefixlen 64 scopeid 0x5
inet6 2002:4452:63ee::21c:b3ff:fe7c:916e prefixlen 64 autoconf
inet 10.0.1.199 netmask 0xffffff00 broadcast 10.0.1.255
ether 00:1c:b3:7c:91:6e
media: autoselect status: active
supported media: autoselect
fw0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 4078
lladdr 00:1d:4f:ff:fe:73:a1:ba
media: autoselect <full-duplex> status: inactive
supported media: autoselect <full-duplex>
vmnet8: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
inet 172.16.192.1 netmask 0xffffff00 broadcast 172.16.192.255
ether 00:50:56:c0:00:08
vmnet1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
inet 172.16.43.1 netmask 0xffffff00 broadcast 172.16.43.255
ether 00:50:56:c0:00:01
Notice the last entry, vmnet1 – the inet address listed there is the address that all of your virtual machines can use to access your localhost. In my case, this is 172.16.43.1
Let’s say you have a local rails app running on http://localhost:3000/ – to access that app from anywhere (your mac or any or your virtual machines) just type http://172.16.43.1:3000/ in your browser.
Just kidding ;->
Ruby Driven Development 4 JavaA screencast illustrating how to...
Ruby Driven Development 4 Java
A screencast illustrating how to install and use Buildr, Rspec and the Story Runner to test first a Java application. It’s long enough (1:15) to explain also some tricks and concepts behind BDD but the main goal is to explain how to move quickly from plain text requirements to working code from Ruby to Java. I’m planning to create a screencast for each user story and talk more about BDD and tracking. Have fun!
Tech Details:
Autonomous Mutant Festival 2008 unofficial webpage
I like Windows Live Mail (Web Edition not the desktop app) and I have been using it for a few months now in addition to my primary Gmail and personal IMAP mail account.
As I upgraded my default browser from Firefox 2x to Firefox 3x, I find that Windows Live doesn't recognize the browser correctly and throws up an error. This is a bug that should be easily rectifiable as Windows Live Mail worked perfectly with the Firefox 2 series.
To Microsoft's credit after wrongly diagnosing my Firefox 3 as an older browser they gave linked to "Upgrade My Browser" and the list included not only MSIE (of course) but also Firefox and Safari. Opera folks will not be too happy but it is a pleasant surprise to see Microsoft (which BTW gets more than its fair share of online "expert" critics) to link to its major competitors.
Here's a screenshot:

Koolhaas’ CCTV
Any really interested readers?
I’ve decided to get rid of dedicated server where this blog runs. Being a bit lazy and having no clue about where do I want to host my blog I’ve decided you, readers, few questions:
Thanks!
Any really interested readers?
I’ve decided to get rid of dedicated server where this blog runs. Being a bit lazy and having no clue about where do I want to host my blog I’ve decided you, readers, few questions:
Thanks!
TimeMachineScheduler - set the backup interval of Time Machine [del.icio.us]
hjw3001 posted a photo:
Alameda County Fair 2008
hjw3001 posted a photo:
Alameda County Fair 2008
hjw3001 posted a photo:
Alameda County Fair 2008
hjw3001 posted a photo:
Alameda County Fair 2008
hjw3001 posted a photo:
Alameda County Fair 2008
hjw3001 posted a photo:
Alameda County Fair 2008
hjw3001 posted a photo:
Alameda County Fair 2008
hjw3001 posted a photo:
Alameda County Fair 2008
hjw3001 posted a photo:
Alameda County Fair 2008
hjw3001 posted a photo:
Alameda County Fair 2008
hjw3001 posted a photo:
Alameda County Fair 2008
hjw3001 posted a photo:
Alameda County Fair 2008
hjw3001 posted a photo:
Alameda County Fair 2008
hjw3001 posted a photo:
Alameda County Fair 2008
hjw3001 posted a photo:
Alameda County Fair 2008
hjw3001 posted a photo:
Alameda County Fair 2008
hjw3001 posted a photo:
Alameda County Fair 2008
hjw3001 posted a photo:
Alameda County Fair 2008
hjw3001 posted a photo:
Alameda County Fair 2008
ZAGG | invisibleSHIELD | Apple iPhone 3G Cases, Screen Protectors, Covers, Shields, Skins, Invisible Shield [del.icio.us]
Tell us what you think of the new BlogSphere feature. We are continually looking to improve and update the
functionality based on your feedback.

Find your next Ruby on Rails project or job.
Exclusive content,
regularly updated - onsite and tele-working positions listed.
My go-to man for rails questions.
-
J.Z, United States