Domanda

I'm using MongoMapper for our primary datastore, and I want to run reporting jobs against the slave nodes in our replica set, rather than the primary. Unfortunately, most of our background jobs are read/write and need to go against the primary.

Is there some way I can do something like the following:

MongoMapper.options({:slave_ok => true})

report.fetch_data  # does all sorts of stuff, uses normal Models, developer doesn't have to go out of his/her way to specify a read preference

MongoMapper.options({:slave_ok => force})

Right now it looks like MongoMapper really just wants you to set read preference as you bring the connection up and then not change it after that.

È stato utile?

Soluzione

MM doesn't natively support this, but it wouldn't be too hard to do it on a per-model basis via a plugin.

module MongoMapper
  module Plugins
    module ReadPreference
      extend ActiveSupport::Concern

      included do
        class << self
          attr_accessor :read_preference
        end
      end

      module ClassMethods
        def query(options={})
          options.merge!(:read => read_preference) if read_preference
          super options
        end

        def with_read_preference(preference)
          self.read_preference = preference
          begin
            yield
          ensure
            self.read_preference = nil
          end
        end
      end
    end
  end
end

MongoMapper::Document.plugin(MongoMapper::Plugins::ReadPreference)

And testing it with my master-only cluster:

2.0.0p0 :002 > User.first
 => <User:0x30a1948 _id: 4cddf1ff98db746691000002, display_name: (Deleted account)>
2.0.0p0 :003 > User.with_read_preference(:secondary) { User.first }
Mongo::ConnectionFailure: No replica set member available for query with read preference matching mode secondary and tags matching [].

It works!

If you wanted a setting global to the connection, you could extend the MongoMapper module with a module attribute, and modify the plugin to look for it first, as well.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top