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.
精彩评论