ruby-on-railsdatabase-replicationmaster-slaveslony

ActiveRecord counter_cache giving stale count with multi_db gem


I'm using the multi-db gem with Slony-I replication on PostgreSQL in a Rails app. This mostly works perfectly, but there is a bit of a replication lag in certain cases. One of the cases involves an ActiveRecord counter_cache.

For clarity, assume the following two models:

class Post < ActiveRecord::Base
  has_many :comments
  ...
end

class Comment < ActiveRecord::Base
  belongs_to :post, :counter_cache => true, :touch => true
  ...
end

After the creation of a comment, rjs is called to update comments count with:

@comment.post.comments_count

With multi-db turned off (or the entry for the slave database pointing the the master db), this works fine. So, I tried something like this:

ActiveRecord::Base.connection_proxy.with_master do
  post=@comment.post
  count=post.comments_count
end

This still gives a stale result. As does setting:

config.cache_classes = false

It looks like the call to with_master isn't working. Any advice on how to determine which database multi-db is using? Or, alternatively, on how to deal with such issues?


Solution

  • In my experience, the further away you get from "mainstream" Rails use cases or the more plugins you stack, the less you can count on advanced functionality to all work together. This is particularly true with ActiveRecord magic.

    If it's important that your comment count stay up to date, do it explicitly. Get rid of the counter_cache and implement after_create and after_destroy callbacks in your Comment model that increment and decrement the count field in your Post model. (Or, perhaps more reliable, set them to the recalculated count for that scope.) It looks less slick but it isn't likely to fail under any reasonable set of dependencies.