ninjudd-cache_version 0.9.3
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/README.rdoc +34 -0
- data/VERSION.yml +4 -0
- data/lib/cache_version.rb +81 -0
- data/test/cache_version_test.rb +26 -0
- data/test/test_helper.rb +30 -0
- metadata +59 -0
data/README.rdoc
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
= CacheVersion
|
|
2
|
+
|
|
3
|
+
CacheVersion lets you maintain a version for any class. This can be used for cache
|
|
4
|
+
invalidation, and RecordCache and MethodCache use it for that. It uses memcache to reduce
|
|
5
|
+
database access when the version of a class hasn't changed.
|
|
6
|
+
|
|
7
|
+
== Usage:
|
|
8
|
+
|
|
9
|
+
CacheVersion.get(User)
|
|
10
|
+
# => 0
|
|
11
|
+
|
|
12
|
+
CacheVersion.increment(User)
|
|
13
|
+
CacheVersion.get(User)
|
|
14
|
+
# => 1
|
|
15
|
+
|
|
16
|
+
# Or you can use the alternate syntax:
|
|
17
|
+
|
|
18
|
+
User.version
|
|
19
|
+
# => 1
|
|
20
|
+
|
|
21
|
+
User.increment_version
|
|
22
|
+
User.version
|
|
23
|
+
# => 2
|
|
24
|
+
|
|
25
|
+
== Install:
|
|
26
|
+
|
|
27
|
+
sudo gem install ninjudd-memcache -s http://gems.github.com
|
|
28
|
+
sudo gem install ninjudd-cache_version -s http://gems.github.com
|
|
29
|
+
|
|
30
|
+
Also, you need to create a migration to make the cache_versions table. See examples/sample_migration.rb
|
|
31
|
+
|
|
32
|
+
== License:
|
|
33
|
+
|
|
34
|
+
Copyright (c) 2009 Justin Balthrop, Geni.com; Published under The MIT License, see LICENSE
|
data/VERSION.yml
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'active_record'
|
|
3
|
+
require 'memcache_extended'
|
|
4
|
+
|
|
5
|
+
module CacheVersion
|
|
6
|
+
def self.db
|
|
7
|
+
if @db.nil?
|
|
8
|
+
@db = ActiveRecord::Base.connection
|
|
9
|
+
@db = @db.send(:master) if defined?(DataFabric::ConnectionProxy) and @db.kind_of?(DataFabric::ConnectionProxy)
|
|
10
|
+
end
|
|
11
|
+
@db
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.cache
|
|
15
|
+
CACHE
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.get(key)
|
|
19
|
+
key = key.to_s
|
|
20
|
+
version_by_key[key] ||= CACHE.get_or_set(cache_key(key)) do
|
|
21
|
+
db.select_value("SELECT version FROM cache_versions WHERE key = '#{key}'").to_i
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.increment(key)
|
|
26
|
+
key = key.to_s
|
|
27
|
+
if get(key) == 0
|
|
28
|
+
db.execute("INSERT INTO cache_versions (key, version) VALUES ('#{key}', 1)")
|
|
29
|
+
else
|
|
30
|
+
db.execute("UPDATE cache_versions SET version = version + 1 WHERE key = '#{key}'")
|
|
31
|
+
end
|
|
32
|
+
invalidate_cache(key)
|
|
33
|
+
get(key)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.invalidate_cache(key)
|
|
37
|
+
key = key.to_s
|
|
38
|
+
cache.delete(cache_key(key))
|
|
39
|
+
version_by_key.delete(key)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def self.clear_cache
|
|
43
|
+
@version_by_key = {}
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
def self.version_by_key
|
|
48
|
+
@version_by_key ||= {}
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def self.cache_key(key)
|
|
52
|
+
"v:#{key}"
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
class Module
|
|
57
|
+
def version(context = nil)
|
|
58
|
+
key = [self, context].compact.join('_')
|
|
59
|
+
CacheVersion.get(key)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def increment_version(context = nil)
|
|
63
|
+
key = [self, context].compact.join('_')
|
|
64
|
+
CacheVersion.increment(key)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
class CacheVersionMigration < ActiveRecord::Migration
|
|
69
|
+
def self.up
|
|
70
|
+
create_table :cache_versions, :id => false do |t|
|
|
71
|
+
t.column :key, :string
|
|
72
|
+
t.column :version, :integer, :default => 0
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
add_index :cache_versions, :key, :unique => true
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def self.down
|
|
79
|
+
drop_table :cache_versions
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
|
2
|
+
|
|
3
|
+
class CacheVersionTest < Test::Unit::TestCase
|
|
4
|
+
context 'with a memcache and db connection' do
|
|
5
|
+
setup do
|
|
6
|
+
system('memcached -d')
|
|
7
|
+
CACHE.servers = ["localhost:11211"]
|
|
8
|
+
CacheVersionMigration.up
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
teardown do
|
|
12
|
+
system('killall memcached')
|
|
13
|
+
CacheVersionMigration.down
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
should 'increment cache version' do
|
|
17
|
+
5.times do |i|
|
|
18
|
+
assert_equal i, Object.version
|
|
19
|
+
Object.increment_version
|
|
20
|
+
assert_equal i + 1, Object.version
|
|
21
|
+
end
|
|
22
|
+
CacheVersion.clear_cache
|
|
23
|
+
assert_equal 5, Object.version
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
data/test/test_helper.rb
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require 'shoulda'
|
|
4
|
+
require 'mocha'
|
|
5
|
+
|
|
6
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + "/../lib"
|
|
7
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + "/../../memcache/lib"
|
|
8
|
+
|
|
9
|
+
require 'cache_version'
|
|
10
|
+
|
|
11
|
+
class Test::Unit::TestCase
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
CACHE = MemCache.new(
|
|
15
|
+
:ttl=>1800,
|
|
16
|
+
:compression=>false,
|
|
17
|
+
:readonly=>false,
|
|
18
|
+
:debug=>false,
|
|
19
|
+
:c_threshold=>10000,
|
|
20
|
+
:urlencode=>false
|
|
21
|
+
)
|
|
22
|
+
ActiveRecord::Base.establish_connection(
|
|
23
|
+
:adapter => "postgresql",
|
|
24
|
+
:host => "localhost",
|
|
25
|
+
:username => "postgres",
|
|
26
|
+
:password => "",
|
|
27
|
+
:database => "record_cache_test"
|
|
28
|
+
)
|
|
29
|
+
ActiveRecord::Migration.verbose = false
|
|
30
|
+
ActiveRecord::Base.connection.client_min_messages = 'panic'
|
metadata
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: ninjudd-cache_version
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.9.3
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Justin Balthrop
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
|
|
12
|
+
date: 2009-07-29 00:00:00 -07:00
|
|
13
|
+
default_executable:
|
|
14
|
+
dependencies: []
|
|
15
|
+
|
|
16
|
+
description: Store the version of any class for cache invalidation
|
|
17
|
+
email: code@justinbalthrop.com
|
|
18
|
+
executables: []
|
|
19
|
+
|
|
20
|
+
extensions: []
|
|
21
|
+
|
|
22
|
+
extra_rdoc_files: []
|
|
23
|
+
|
|
24
|
+
files:
|
|
25
|
+
- README.rdoc
|
|
26
|
+
- VERSION.yml
|
|
27
|
+
- lib/cache_version.rb
|
|
28
|
+
- test/cache_version_test.rb
|
|
29
|
+
- test/test_helper.rb
|
|
30
|
+
has_rdoc: true
|
|
31
|
+
homepage: http://github.com/ninjudd/cache_version
|
|
32
|
+
licenses:
|
|
33
|
+
post_install_message:
|
|
34
|
+
rdoc_options:
|
|
35
|
+
- --inline-source
|
|
36
|
+
- --charset=UTF-8
|
|
37
|
+
require_paths:
|
|
38
|
+
- lib
|
|
39
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
40
|
+
requirements:
|
|
41
|
+
- - ">="
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
version: "0"
|
|
44
|
+
version:
|
|
45
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
46
|
+
requirements:
|
|
47
|
+
- - ">="
|
|
48
|
+
- !ruby/object:Gem::Version
|
|
49
|
+
version: "0"
|
|
50
|
+
version:
|
|
51
|
+
requirements: []
|
|
52
|
+
|
|
53
|
+
rubyforge_project:
|
|
54
|
+
rubygems_version: 1.3.5
|
|
55
|
+
signing_key:
|
|
56
|
+
specification_version: 2
|
|
57
|
+
summary: Store the version of any class for cache invalidation
|
|
58
|
+
test_files: []
|
|
59
|
+
|