开发者

rails 3 caching site settings with ability to reload cache without server restart and third-party tools

I need some solution to make following functionality in my RoR 3 site:

Site needs a user rating system, where users get points for performing some actions (like getting points for answering questions on stackoverflow).

The problems are:

1) I need ability to re-assign amount of points for some actions (not so often, but I can't restart Mongrel each time I need to re-assign, so in-code constants and YAML don't suit)

2) I can't use simple Active Record, because on 5000 users I'll do too many queries for each user action, so I need caching, and an ability to reset cache on re-assignment

3) I 开发者_C百科would like to make it without memcached or something like this, cause my server hardware is old enough.

Does anyone know such solution?


What about something like this ?

@@points_loaded = false
@@points

def load_action_points 
    if (File.ctime("setting.yml")  < Time.now) || !@@points_loaded
        @@points = YAML::load( File.open( 'setting.yml' ) )
        @@points_loaded = true 
    else
        @@points
end 

or use A::B and cache the DB lookups

class ActionPoints < ActiveRecord::Base
  extend ActiveSupport::Memoizable


  def points
   self.all
  end

  memoize :points
end

You also cache the points in the User model, something like this .. pseudocode...

class User < A::B

  serialize :points


def after_save
points = PointCalculator(self).points
end 

end 

and....

  class PointCalculator

        def initialize(user)
        @@total_points = 0
          user.actions.each do |action|
             p = action.times * ActionPoints.find_by_action("did_something_cool").points
@@total_points = @@total_points + p 
          end 

        end

    def points
     @@total_points
    end

      end 


I've found some simple solution, but it works only if you have one RoR server instance:

class Point < ActiveRecord::Base
  @@cache = {}

  validates :name, :presence => true
  validates :amount, :numericality => true, :presence => true

  after_save :load_to_cache, :revaluate_users

  def self.get_for(str)
    @@cache = Hash[Point.all.map { |point| [point.name.to_sym, point] }] if @@cache == {} #for cache initializing
    @@cache[str.to_sym].amount
  end

  private

  def load_to_cache
    @@cache[self.name.to_sym] = self
  end

  def revaluate_users
   #schedule some background method, that will update all users' scores
  end
end

If you know a solution for multiple server instances without installing memcached, I will be very glad to see it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜