Added cache for application settings (Setting model).
Once the values are cached, only one database query is done at each user request (to check if the cache is still valid). git-svn-id: http://redmine.rubyforge.org/svn/trunk@685 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
404bfce446
commit
6bdc13b33d
|
@ -32,6 +32,7 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
|
||||
def user_setup
|
||||
Setting.check_cache
|
||||
if session[:user_id]
|
||||
# existing session
|
||||
User.current = User.find(session[:user_id])
|
||||
|
|
|
@ -24,24 +24,27 @@ class Setting < ActiveRecord::Base
|
|||
validates_inclusion_of :name, :in => @@available_settings.keys
|
||||
validates_numericality_of :value, :only_integer => true, :if => Proc.new { |setting| @@available_settings[setting.name]['format'] == 'int' }
|
||||
|
||||
def self.get(name)
|
||||
name = name.to_s
|
||||
setting = find_by_name(name)
|
||||
setting ||= new(:name => name, :value => @@available_settings[name]['default']) if @@available_settings.has_key? name
|
||||
setting
|
||||
end
|
||||
# Hash used to cache setting values
|
||||
@cached_settings = {}
|
||||
@cached_cleared_on = Time.now
|
||||
|
||||
# Returns the value of the setting named name
|
||||
def self.[](name)
|
||||
get(name).value
|
||||
value = @cached_settings[name]
|
||||
value ? value : (@cached_settings[name] = find_or_default(name).value)
|
||||
end
|
||||
|
||||
def self.[]=(name, value)
|
||||
setting = get(name)
|
||||
setting = find_or_default(name)
|
||||
setting.value = (value ? value.to_s : "")
|
||||
@cached_settings[name] = nil
|
||||
setting.save
|
||||
setting.value
|
||||
end
|
||||
|
||||
# Defines getter and setter for each setting
|
||||
# Then setting values can be read using: Setting.some_setting_name
|
||||
# or set using Setting.some_setting_name = "some value"
|
||||
@@available_settings.each do |name, params|
|
||||
src = <<-END_SRC
|
||||
def self.#{name}
|
||||
|
@ -58,4 +61,26 @@ class Setting < ActiveRecord::Base
|
|||
END_SRC
|
||||
class_eval src, __FILE__, __LINE__
|
||||
end
|
||||
|
||||
# Checks if settings have changed since the values were read
|
||||
# and clears the cache hash if it's the case
|
||||
# Called once per request
|
||||
def self.check_cache
|
||||
settings_updated_on = Setting.maximum(:updated_on)
|
||||
if settings_updated_on && @cached_cleared_on <= settings_updated_on
|
||||
@cached_settings.clear
|
||||
@cached_cleared_on = Time.now
|
||||
logger.info "Settings cache cleared." if logger
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
# Returns the Setting instance for the setting named name
|
||||
# (record found in database or new record with default value)
|
||||
def self.find_or_default(name)
|
||||
name = name.to_s
|
||||
raise "There's no setting named #{name}" unless @@available_settings.has_key?(name)
|
||||
setting = find_by_name(name)
|
||||
setting ||= new(:name => name, :value => @@available_settings[name]['default']) if @@available_settings.has_key? name
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
class AddSettingsUpdatedOn < ActiveRecord::Migration
|
||||
def self.up
|
||||
add_column :settings, :updated_on, :timestamp
|
||||
# set updated_on
|
||||
Setting.find(:all).each(&:save)
|
||||
end
|
||||
|
||||
def self.down
|
||||
remove_column :settings, :updated_on
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue