From c51a32ac23fb6c35553a6d665934bf83ae52439e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Felix=20Sch=C3=A4fer?= <f.schaefer@finn.de>
Date: Wed, 25 May 2011 17:11:16 +0200
Subject: [PATCH] Use Rails.cache to cache application settings. #350

---
 app/models/setting.rb                         | 21 ++++++++-----------
 test/functional/documents_controller_test.rb  |  2 +-
 test/functional/news_controller_test.rb       |  2 +-
 ...repositories_filesystem_controller_test.rb |  2 +-
 test/unit/comment_test.rb                     |  2 +-
 test/unit/document_test.rb                    |  2 +-
 test/unit/news_test.rb                        |  2 +-
 test/unit/repository_filesystem_test.rb       |  2 +-
 8 files changed, 16 insertions(+), 19 deletions(-)

diff --git a/app/models/setting.rb b/app/models/setting.rb
index 8f5b83b05..612bb286b 100644
--- a/app/models/setting.rb
+++ b/app/models/setting.rb
@@ -84,10 +84,6 @@ class Setting < ActiveRecord::Base
   validates_uniqueness_of :name
   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' }  
-
-  # Hash used to cache setting values
-  @cached_settings = {}
-  @cached_cleared_on = Time.now
   
   def value
     v = read_attribute(:value)
@@ -104,16 +100,15 @@ class Setting < ActiveRecord::Base
   
   # Returns the value of the setting named name
   def self.[](name)
-    v = @cached_settings[name]
-    v ? v : (@cached_settings[name] = find_or_default(name).value)
+    Marshal.load(Rails.cache.fetch("chiliproject/setting/#{name}") {Marshal.dump(find_or_default(name).value)}).freeze
   end
   
   def self.[]=(name, v)
     setting = find_or_default(name)
     setting.value = (v ? v : "")
-    @cached_settings[name] = nil
+    Rails.cache.delete "chiliproject/setting/#{name}"
     setting.save
-    setting.value
+    setting.value.freeze
   end
   
   # Defines getter and setter for each setting
@@ -150,10 +145,12 @@ class Setting < ActiveRecord::Base
   # 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
+    cache_cleared_on = Rails.cache.read('chiliproject/setting-cleared_on')
+    cache_cleared_on = cache_cleared_on ? Marshal.load(cache_cleared_on) : Time.now
+    if settings_updated_on && cache_cleared_on <= settings_updated_on
+      Rails.cache.delete_matched( /^chiliproject\/setting\/.+$/ )
+      Rails.cache.write('chiliproject/setting-cleared_on', Marshal.dump(Time.now))
+      logger.info 'Settings cache cleared.' if logger
     end
   end
   
diff --git a/test/functional/documents_controller_test.rb b/test/functional/documents_controller_test.rb
index a774494b5..fc7af9eff 100644
--- a/test/functional/documents_controller_test.rb
+++ b/test/functional/documents_controller_test.rb
@@ -67,7 +67,7 @@ LOREM
   
   def test_new_with_one_attachment
     ActionMailer::Base.deliveries.clear
-    Setting.notified_events << 'document_added'
+    Setting.notified_events = Setting.notified_events.dup << 'document_added'
     @request.session[:user_id] = 2
     set_tmp_attachments_directory
     
diff --git a/test/functional/news_controller_test.rb b/test/functional/news_controller_test.rb
index 56725013b..16ec22827 100644
--- a/test/functional/news_controller_test.rb
+++ b/test/functional/news_controller_test.rb
@@ -67,7 +67,7 @@ class NewsControllerTest < ActionController::TestCase
   
   def test_post_create
     ActionMailer::Base.deliveries.clear
-    Setting.notified_events << 'news_added'
+    Setting.notified_events = Setting.notified_events.dup << 'news_added'
 
     @request.session[:user_id] = 2
     post :create, :project_id => 1, :news => { :title => 'NewsControllerTest',
diff --git a/test/functional/repositories_filesystem_controller_test.rb b/test/functional/repositories_filesystem_controller_test.rb
index aeb5ab9bd..e88c2f604 100644
--- a/test/functional/repositories_filesystem_controller_test.rb
+++ b/test/functional/repositories_filesystem_controller_test.rb
@@ -33,7 +33,7 @@ class RepositoriesFilesystemControllerTest < ActionController::TestCase
     @request    = ActionController::TestRequest.new
     @response   = ActionController::TestResponse.new
     User.current = nil
-    Setting.enabled_scm << 'Filesystem' unless Setting.enabled_scm.include?('Filesystem')
+    Setting.enabled_scm = Setting.enabled_scm.dup << 'Filesystem' unless Setting.enabled_scm.include?('Filesystem')
     @repository = Repository::Filesystem.create(
                       :project => Project.find(PRJ_ID),
                       :url     => REPOSITORY_PATH,
diff --git a/test/unit/comment_test.rb b/test/unit/comment_test.rb
index 02be8fc5c..cc24d9765 100644
--- a/test/unit/comment_test.rb
+++ b/test/unit/comment_test.rb
@@ -33,7 +33,7 @@ class CommentTest < ActiveSupport::TestCase
   end
   
   def test_create_should_send_notification
-    Setting.notified_events << 'news_comment_added'
+    Setting.notified_events = Setting.notified_events.dup << 'news_comment_added'
     Watcher.create!(:watchable => @news, :user => @jsmith)
     
     assert_difference 'ActionMailer::Base.deliveries.size' do
diff --git a/test/unit/document_test.rb b/test/unit/document_test.rb
index 2478ea71d..82e5ef874 100644
--- a/test/unit/document_test.rb
+++ b/test/unit/document_test.rb
@@ -27,7 +27,7 @@ class DocumentTest < ActiveSupport::TestCase
   
   def test_create_should_send_email_notification
     ActionMailer::Base.deliveries.clear
-    Setting.notified_events << 'document_added'
+    Setting.notified_events = Setting.notified_events.dup << 'document_added'
     doc = Document.new(:project => Project.find(1), :title => 'New document', :category => Enumeration.find_by_name('User documentation'))
 
     assert doc.save
diff --git a/test/unit/news_test.rb b/test/unit/news_test.rb
index 2dba2c345..c9fef6b27 100644
--- a/test/unit/news_test.rb
+++ b/test/unit/news_test.rb
@@ -30,7 +30,7 @@ class NewsTest < ActiveSupport::TestCase
   
   def test_create_should_send_email_notification
     ActionMailer::Base.deliveries.clear
-    Setting.notified_events << 'news_added'
+    Setting.notified_events = Setting.notified_events.dup << 'news_added'
     news = Project.find(:first).news.new(valid_news)
 
     assert news.save
diff --git a/test/unit/repository_filesystem_test.rb b/test/unit/repository_filesystem_test.rb
index e1287d282..ce28a1eb7 100644
--- a/test/unit/repository_filesystem_test.rb
+++ b/test/unit/repository_filesystem_test.rb
@@ -25,7 +25,7 @@ class RepositoryFilesystemTest < ActiveSupport::TestCase
 
   def setup
     @project = Project.find(3)
-    Setting.enabled_scm << 'Filesystem' unless Setting.enabled_scm.include?('Filesystem')
+    Setting.enabled_scm = Setting.enabled_scm.dup << 'Filesystem' unless Setting.enabled_scm.include?('Filesystem')
     assert @repository = Repository::Filesystem.create(
                             :project => @project, :url => REPOSITORY_PATH)
   end
-- 
GitLab