revo-cache_fu 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG ADDED
File without changes
data/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ Copyright (c) 2007 Chris Wanstrath
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ the Software, and to permit persons to whom the Software is furnished to do so,
8
+ subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,17 @@
1
+ == cache_fu
2
+
3
+ A rewrite of acts_as_cached.
4
+
5
+ == Changes from acts_as_cached 1
6
+
7
+ - You can no longer set a 'ttl' method on a class. Instead,
8
+ pass :ttl to acts_as_cached:
9
+ >> acts_as_cached :ttl => 15.minutes
10
+
11
+ - The is_cached? method is aliased as cached?
12
+
13
+ - set_cache on an instance can take a ttl
14
+ >> @story.set_cache(15.days)
15
+
16
+
17
+ Chris Wanstrath [ chris[at]ozmm[dot]org ]
data/Rakefile ADDED
@@ -0,0 +1,54 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+ require 'load_multi_rails_rake_tasks'
5
+
6
+ desc "Run all the tests"
7
+ task :default => :test
8
+
9
+ test_files = FileList['test/*test.rb']
10
+
11
+ desc 'Test the cache_fu plugin.'
12
+ task :test do
13
+ test_files.each do |file|
14
+ ruby "#{file}"
15
+ end
16
+ end
17
+
18
+ desc 'Test the cache_fu plugin against Rails 1.2.5'
19
+ task :test_with_125 do
20
+ ENV['MULTIRAILS_RAILS_VERSION'] = '1.2.5'
21
+ test_files.each do |file|
22
+ ruby "#{file}"
23
+ end
24
+ end
25
+
26
+ desc "Run cache_fu tests using a memcache daemon"
27
+ task :test_with_memcache do
28
+ test_files.each do |file|
29
+ ruby "#{file} with-memcache"
30
+ end
31
+ end
32
+
33
+ desc 'Generate RDoc documentation for the cache_fu plugin.'
34
+ Rake::RDocTask.new(:rdoc) do |rdoc|
35
+ files = ['README', 'LICENSE', 'lib/**/*.rb']
36
+ rdoc.rdoc_files.add(files)
37
+ rdoc.main = "README" # page to start on
38
+ rdoc.title = "cache_fu"
39
+ rdoc.template = File.exists?(t="/Users/chris/ruby/projects/err/rock/template.rb") ? t : "/var/www/rock/template.rb"
40
+ rdoc.rdoc_dir = 'doc' # rdoc output folder
41
+ rdoc.options << '--inline-source'
42
+ end
43
+
44
+ require 'jeweler'
45
+ Jeweler::Tasks.new do |gemspec|
46
+ gemspec.name = "cache_fu"
47
+ gemspec.summary = "Summarize your gem"
48
+ gemspec.description = "Describe your gem"
49
+ gemspec.email = "chris@ozmm.org"
50
+ gemspec.homepage = "http://github.com/defunkt/cache_fu"
51
+ gemspec.description = "DESCRIPTION!"
52
+ gemspec.authors = ["Chris Wanstrath"]
53
+ end
54
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
data/cache_fu.gemspec ADDED
@@ -0,0 +1,77 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{cache_fu}
8
+ s.version = "1.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Chris Wanstrath"]
12
+ s.date = %q{2009-08-18}
13
+ s.description = %q{DESCRIPTION!}
14
+ s.email = %q{chris@ozmm.org}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README"
18
+ ]
19
+ s.files = [
20
+ "CHANGELOG",
21
+ "LICENSE",
22
+ "README",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "cache_fu.gemspec",
26
+ "defaults/extensions.rb.default",
27
+ "defaults/memcached.yml.default",
28
+ "defaults/memcached_ctl.default",
29
+ "init.rb",
30
+ "install.rb",
31
+ "lib/acts_as_cached.rb",
32
+ "lib/acts_as_cached/benchmarking.rb",
33
+ "lib/acts_as_cached/cache_methods.rb",
34
+ "lib/acts_as_cached/config.rb",
35
+ "lib/acts_as_cached/disabled.rb",
36
+ "lib/acts_as_cached/fragment_cache.rb",
37
+ "lib/acts_as_cached/local_cache.rb",
38
+ "lib/acts_as_cached/memcached_rails.rb",
39
+ "lib/acts_as_cached/recipes.rb",
40
+ "tasks/memcached.rake",
41
+ "test/benchmarking_test.rb",
42
+ "test/cache_test.rb",
43
+ "test/config_test.rb",
44
+ "test/disabled_test.rb",
45
+ "test/extensions_test.rb",
46
+ "test/fragment_cache_test.rb",
47
+ "test/helper.rb",
48
+ "test/local_cache_test.rb",
49
+ "test/sti_test.rb"
50
+ ]
51
+ s.homepage = %q{http://github.com/defunkt/cache_fu}
52
+ s.rdoc_options = ["--charset=UTF-8"]
53
+ s.require_paths = ["lib"]
54
+ s.rubygems_version = %q{1.3.3}
55
+ s.summary = %q{Summarize your gem}
56
+ s.test_files = [
57
+ "test/sti_test.rb",
58
+ "test/benchmarking_test.rb",
59
+ "test/local_cache_test.rb",
60
+ "test/config_test.rb",
61
+ "test/extensions_test.rb",
62
+ "test/fragment_cache_test.rb",
63
+ "test/disabled_test.rb",
64
+ "test/cache_test.rb",
65
+ "test/helper.rb"
66
+ ]
67
+
68
+ if s.respond_to? :specification_version then
69
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
70
+ s.specification_version = 3
71
+
72
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
73
+ else
74
+ end
75
+ else
76
+ end
77
+ end
@@ -0,0 +1,40 @@
1
+ ##
2
+ # Copy this file to vendor/plugins/acts_as_cached/extensions.rb if you
3
+ # wish to extend acts_as_cached with your own instance or class methods.
4
+ #
5
+ # You can, of course, do this directly in your cached classes,
6
+ # but keeping your custom methods here allows you to define
7
+ # methods for all cached objects DRYly.
8
+ module ActsAsCached
9
+ module Extensions
10
+ module ClassMethods
11
+ ##
12
+ # All acts_as_cached classes will be extended with
13
+ # this method.
14
+ #
15
+ # >> Story.multi_get_cache(13, 353, 1231, 505)
16
+ # => [<Story:13>, <Story:353>, ...]
17
+ def multi_get_cache(*ids)
18
+ ids.flatten.map { |id| get_cache(id) }
19
+ end
20
+ end
21
+
22
+ module InstanceMethods
23
+ ##
24
+ # All instances of a acts_as_cached class will be
25
+ # extended with this method.
26
+ #
27
+ # => story = Story.get_cache(1)
28
+ # => <Story:1>
29
+ # >> story.reset_included_caches
30
+ # => true
31
+ def reset_included_caches
32
+ return false unless associations = cache_config[:include]
33
+ associations.each do |association|
34
+ Array(send(association)).each { |item| item.reset_cache }
35
+ end
36
+ true
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,34 @@
1
+ defaults:
2
+ ttl: 1800
3
+ readonly: false
4
+ urlencode: false
5
+ c_threshold: 10000
6
+ compression: true
7
+ debug: false
8
+ namespace: app
9
+ sessions: false
10
+ session_servers: false
11
+ fragments: false
12
+ memory: 64
13
+ servers: localhost:11211
14
+ benchmarking: true
15
+ raise_errors: true
16
+ fast_hash: false
17
+ fastest_hash: false
18
+
19
+ development:
20
+ sessions: false
21
+ fragments: false
22
+ servers: localhost:11211
23
+
24
+ # turn off caching
25
+ test:
26
+ disabled: true
27
+
28
+ production:
29
+ memory: 256
30
+ benchmarking: false
31
+ servers:
32
+ - 192.185.254.121:11211
33
+ - 192.185.254.138:11211
34
+ - 192.185.254.160:11211
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env ruby
2
+ # By atmos@atmos.org
3
+ # this goes in your script/ directory
4
+ # it parses your memcached.yml file and hooks you up w/ some info
5
+ # it keeps you from having to mess w/ stale memcached daemons for whatever reason.
6
+ require 'yaml'
7
+ require 'timeout'
8
+ require 'erb'
9
+
10
+ class MemcachedCtl
11
+ attr_accessor :memcached, :memory, :pids, :servers, :ip_address, :ethernet_device
12
+
13
+ def initialize
14
+ env = ENV['RAILS_ENV'] || 'development'
15
+ self.memcached = `which memcached`.chomp
16
+ self.servers = [ ]
17
+ self.pids = { }
18
+ self.ethernet_device = ENV['ETH'] || 'eth0'
19
+ self.ip_address = get_ip_address || '0.0.0.0'
20
+ self.memory = '128'
21
+
22
+ config = YAML.load(ERB.new(IO.read((File.expand_path(File.dirname(__FILE__) + "/../config/memcached.yml")))).result)
23
+ self.servers = [ config['defaults']['servers'] ].flatten rescue ['127.0.0.1:11211']
24
+ self.servers = [ config[env]['servers'] ].flatten if config[env]['servers']
25
+ self.servers.reject! { |server| host,port = server.split(/:/); self.ip_address == host }
26
+ self.memory = config[env]['memory'] unless config[env]['memory'].nil?
27
+
28
+ each_server do |host,port|
29
+ `ps auwwx | grep memcached | grep '\\-l #{ip_address} \\-p #{port}' | grep -v grep`.split(/\n/).each do |line|
30
+ self.pids[port] = line.split(/\s+/)[1]
31
+ end
32
+ self.pids[port] ||= 'Down'
33
+ end
34
+ end
35
+
36
+ def execute(cmd)
37
+ send(cmd) rescue usage
38
+ end
39
+
40
+ def restart; stop; sleep 1; start end
41
+
42
+ def status
43
+ each_server { |host,port| puts "Port #{port} -> #{pids[port] =~ /\d+/ ? 'Up' : 'Down'}" }
44
+ end
45
+
46
+ def kill
47
+ each_server { |host,port| `kill -9 #{pids[port]} > /dev/null 2>&1` if pids[port] =~ /\d+/ }
48
+ end
49
+
50
+ def stop; kill end
51
+
52
+ def start
53
+ each_server do |host,port|
54
+ `#{memcached} -d -m #{memory} -l #{ip_address} -p #{port}`
55
+ STDERR.puts "Try memcached_ctl status" unless $? == 0
56
+ end
57
+ end
58
+
59
+ def usage
60
+ methods = %w[start stop restart kill status]
61
+ puts "Usage: script/memcached_ctl [ " + (methods * ' | ') + " ]"
62
+ end
63
+
64
+ protected
65
+ def each_server
66
+ servers.each do |server|
67
+ host, port = server.split(/:/)
68
+ yield host, port
69
+ end
70
+ end
71
+
72
+ def get_ip_address # this works on linux you might have to tweak this on other oses
73
+ line = `/sbin/ifconfig #{ethernet_device} | grep inet | grep -v inet6`.chomp
74
+ if line =~ /\s*inet addr:((\d+\.){3}\d+)\s+.*/
75
+ self.ip_address = $1
76
+ end
77
+ end
78
+ end
79
+ ###########################################################################
80
+
81
+ MemcachedCtl.new.execute(ARGV.first)
data/init.rb ADDED
@@ -0,0 +1,34 @@
1
+ begin
2
+ require 'memcache'
3
+ rescue LoadError
4
+ end
5
+
6
+ begin
7
+ require 'memcached'
8
+ rescue LoadError
9
+ end
10
+
11
+ begin
12
+ require 'mem_cache_with_consistent_hashing'
13
+ rescue LoadError
14
+ end
15
+
16
+ puts "=> You should be using the `memcache-client' gem. You're using RubyMemcache!" if Object.const_defined?(:RubyMemcache)
17
+
18
+ require 'acts_as_cached'
19
+
20
+ Object.send :include, ActsAsCached::Mixin
21
+
22
+ unless File.exists? config_file = File.join(RAILS_ROOT, 'config', 'memcached.yml')
23
+ error = "No config file found. Make sure you used `script/plugin install' and have memcached.yml in your config directory."
24
+ puts error
25
+ logger.error error
26
+ exit!
27
+ end
28
+
29
+ ActsAsCached.config = YAML.load(ERB.new(IO.read(config_file)).result)
30
+
31
+ begin
32
+ require 'extensions'
33
+ rescue LoadError
34
+ end
data/install.rb ADDED
@@ -0,0 +1,58 @@
1
+ ##
2
+ # Do some checks.
3
+ puts
4
+
5
+ $errors = 0
6
+
7
+ puts "** Checking for memcached in path..."
8
+ if `which memcached`.strip.empty?
9
+ $errors += 1
10
+ puts "!! Couldn't find memcached in your path. Are you sure you installed it? !!"
11
+ puts "!! Check the README for help. You can't use acts_as_cached without it. !!"
12
+ end
13
+
14
+ puts "** Checking for memcache-client gem..."
15
+ begin
16
+ require 'rubygems'
17
+ require 'memcache'
18
+ rescue LoadError
19
+ $errors += 1
20
+ puts "!! Couldn't find memcache-client gem. You can't use acts_as_cached without it. !!"
21
+ puts "!! $ sudo gem install memcache-client !!"
22
+ end
23
+
24
+ require 'fileutils'
25
+ def copy_file(in_file, out_file)
26
+ puts "** Trying to copy #{File.basename(in_file)} to #{out_file}..."
27
+ begin
28
+ if File.exists? out_file
29
+ puts "!! You already have a #{out_file}. " +
30
+ "Please check the default for new settings or format changes. !!"
31
+ puts "!! You can find the default at #{in_file}. !!"
32
+ $errors += 1
33
+ else
34
+ FileUtils.cp(in_file, out_file)
35
+ end
36
+ rescue
37
+ $errors += 1
38
+ puts "!! Error copying #{File.basename(in_file)} to #{out_file}. Please try by hand. !!"
39
+ end
40
+ end
41
+
42
+ defaults_dir = File.join(File.dirname(__FILE__), 'defaults')
43
+
44
+ config_yaml = File.join('.', 'config', 'memcached.yml')
45
+ default_yaml = File.join(defaults_dir, 'memcached.yml.default')
46
+ copy_file(default_yaml, config_yaml)
47
+
48
+ memcached_ctl = File.join('.', 'script', 'memcached_ctl')
49
+ default_ctl = File.join(defaults_dir, 'memcached_ctl.default')
50
+ copy_file(default_ctl, memcached_ctl)
51
+
52
+ puts
53
+ print $errors.zero? ? "**" : "!!"
54
+ print " acts_as_cached installed with #{$errors.zero? ? 'no' : $errors} errors."
55
+ print " Please edit the memcached.yml file to your liking."
56
+ puts $errors.zero? ? "" : " !!"
57
+ puts "** Now would be a good time to check out the README. Enjoy your day."
58
+ puts
@@ -0,0 +1,87 @@
1
+ require 'benchmark'
2
+
3
+ module ActsAsCached
4
+ module Benchmarking #:nodoc:
5
+ def self.cache_runtime
6
+ @@cache_runtime ||= 0.0
7
+ end
8
+
9
+ def self.cache_reset_runtime
10
+ @@cache_runtime = nil
11
+ end
12
+
13
+ def cache_benchmark(title, log_level = Logger::DEBUG, use_silence = true)
14
+ return yield unless logger && logger.level == log_level
15
+ result = nil
16
+
17
+ seconds = Benchmark.realtime {
18
+ result = use_silence ? ActionController::Base.silence { yield } : yield
19
+ }
20
+
21
+ @@cache_runtime ||= 0.0
22
+ @@cache_runtime += seconds
23
+
24
+ logger.add(log_level, "==> #{title} (#{'%.5f' % seconds})")
25
+ result
26
+ end
27
+
28
+ def fetch_cache_with_benchmarking(*args)
29
+ cache_benchmark "Got #{cache_key args.first} from cache." do
30
+ fetch_cache_without_benchmarking(*args)
31
+ end
32
+ end
33
+
34
+ def set_cache_with_benchmarking(*args)
35
+ cache_benchmark "Set #{cache_key args.first} to cache." do
36
+ set_cache_without_benchmarking(*args)
37
+ end
38
+ end
39
+
40
+ def expire_cache_with_benchmarking(*args)
41
+ cache_benchmark "Deleted #{cache_key args.first} from cache." do
42
+ expire_cache_without_benchmarking(*args)
43
+ end
44
+ end
45
+
46
+ def self.add_to(klass)
47
+ return if klass.respond_to? :fetch_cache_with_benchmarking
48
+ klass.extend self
49
+
50
+ class << klass
51
+ alias_method_chain :fetch_cache, :benchmarking
52
+ alias_method_chain :set_cache, :benchmarking
53
+ alias_method_chain :expire_cache, :benchmarking
54
+
55
+ def logger; RAILS_DEFAULT_LOGGER end unless respond_to? :logger
56
+ end
57
+ end
58
+
59
+ def self.inject_into_logs!
60
+ if ActionController::Base.private_method_defined?(:rendering_runtime)
61
+ # Rails < 2.2
62
+ ActionController::Base.send :alias_method_chain, :rendering_runtime, :memcache
63
+ elsif ActionController::Base.private_method_defined?(:view_runtime)
64
+ # Rails >= 2.2
65
+ ActionController::Base.send :alias_method_chain, :view_runtime, :memcache
66
+ else
67
+ raise "Unknown Rails Version?!"
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ module ActionController
74
+ class Base
75
+ def rendering_runtime_with_memcache(runtime) #:nodoc:
76
+ cache_runtime = ActsAsCached::Benchmarking.cache_runtime
77
+ ActsAsCached::Benchmarking.cache_reset_runtime
78
+ rendering_runtime_without_memcache(runtime) + (cache_runtime.nonzero? ? " | Memcache: #{"%.5f" % cache_runtime}" : '')
79
+ end
80
+
81
+ def view_runtime_with_memcache #:nodoc:
82
+ cache_runtime = ActsAsCached::Benchmarking.cache_runtime
83
+ ActsAsCached::Benchmarking.cache_reset_runtime
84
+ view_runtime_without_memcache + (cache_runtime.nonzero? ? ", Memcache: #{"%.0f" % (cache_runtime * 1000)}" : '')
85
+ end
86
+ end
87
+ end