cachier 0.0.1
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/lib/cachier.rb +104 -0
- data/lib/cachier/controller_helper.rb +34 -0
- data/lib/cachier/cucumber.rb +6 -0
- data/lib/cachier/matchers.rb +39 -0
- data/lib/cachier/version.rb +3 -0
- data/lib/controller_helper.rb +34 -0
- data/lib/cucumber.rb +6 -0
- data/lib/matchers.rb +39 -0
- data/lib/railtie.rb +8 -0
- data/lib/version.rb +3 -0
- metadata +131 -0
data/lib/cachier.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
# Cachier
|
2
|
+
module Cachier
|
3
|
+
extend self
|
4
|
+
|
5
|
+
CACHE_KEY = 'cachier-tags'
|
6
|
+
|
7
|
+
def perform_caching?
|
8
|
+
::ApplicationController.perform_caching
|
9
|
+
end
|
10
|
+
|
11
|
+
# Fetch from cache, this function accepts a block
|
12
|
+
def fetch(cache_key, cache_params = {})
|
13
|
+
tags = cache_params.delete(:tag) || []
|
14
|
+
store_fragment(cache_key, tags)
|
15
|
+
|
16
|
+
if block_given?
|
17
|
+
returned_object = Rails.cache.fetch(cache_key, cache_params) {
|
18
|
+
yield
|
19
|
+
}
|
20
|
+
else
|
21
|
+
Rails.cache.read(cache_key)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def store_fragment(fragment, *tags)
|
26
|
+
return unless perform_caching?
|
27
|
+
|
28
|
+
tags.each do |tag|
|
29
|
+
fragments = Rails.cache.fetch(tag) || []
|
30
|
+
Rails.cache.write(tag, fragments + [fragment])
|
31
|
+
end
|
32
|
+
|
33
|
+
add_tags_to_tag_list(tags)
|
34
|
+
end
|
35
|
+
|
36
|
+
def expire(*tags)
|
37
|
+
return unless perform_caching?
|
38
|
+
|
39
|
+
# delete them from the cache
|
40
|
+
tags.each do |tag|
|
41
|
+
if fragment_keys = Rails.cache.fetch(tag)
|
42
|
+
fragment_keys.each do |fragment_key|
|
43
|
+
Rails.cache.delete(fragment_key)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
Rails.cache.delete(tag)
|
48
|
+
end
|
49
|
+
|
50
|
+
# now remove them from the list
|
51
|
+
# of stored tags
|
52
|
+
remove_tags_from_tag_list(tags)
|
53
|
+
end
|
54
|
+
|
55
|
+
def tags
|
56
|
+
Rails.cache.fetch(CACHE_KEY) || []
|
57
|
+
end
|
58
|
+
|
59
|
+
def clear
|
60
|
+
expire(*tags)
|
61
|
+
Rails.cache.delete(CACHE_KEY)
|
62
|
+
end
|
63
|
+
|
64
|
+
def wipe
|
65
|
+
clear
|
66
|
+
end
|
67
|
+
|
68
|
+
def keys
|
69
|
+
tags.inject([]) do |arry, tag|
|
70
|
+
arry += (Rails.cache.fetch(tag) || [])
|
71
|
+
end.compact
|
72
|
+
end
|
73
|
+
|
74
|
+
def keys_for(tag)
|
75
|
+
Rails.cache.fetch(tag) || []
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
def add_tags_to_tag_list(*tags)
|
80
|
+
cachier_tags = get_cachier_tags
|
81
|
+
|
82
|
+
cachier_tags = (cachier_tags + tags).uniq
|
83
|
+
write_cachier_tags(cachier_tags)
|
84
|
+
end
|
85
|
+
|
86
|
+
def write_cachier_tags(cachier_tags)
|
87
|
+
Rails.cache.write(CACHE_KEY, cachier_tags)
|
88
|
+
end
|
89
|
+
|
90
|
+
def remove_tags_from_tag_list(*tags)
|
91
|
+
cachier_tags = get_cachier_tags
|
92
|
+
|
93
|
+
cachier_tags = (cachier_tags - tags).uniq
|
94
|
+
write_cachier_tags(cachier_tags)
|
95
|
+
end
|
96
|
+
|
97
|
+
def get_cachier_tags
|
98
|
+
cachier_tags = Rails.cache.fetch(CACHE_KEY) || []
|
99
|
+
cachier_tags
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
require 'cachier/controller_helper'
|
104
|
+
require 'cachier/matchers'
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Hooks into ApplicationController's write_fragment method.
|
2
|
+
# write_fragment is used for action and fragment caching.
|
3
|
+
# Create an alias method chain to call our customer method
|
4
|
+
# which stores the associated key with the tag in a
|
5
|
+
# Redis Set. Then we can expire all those keys from anywhere
|
6
|
+
# in the code using Rails.cache.delete
|
7
|
+
#
|
8
|
+
# I use alias_method_chain instead of calling 'super'
|
9
|
+
# because there is a very rare case where someone
|
10
|
+
# may have redfined 'write_fragment' in their own
|
11
|
+
# controllers. Using an alias method chain
|
12
|
+
# keeps those methods intact.
|
13
|
+
|
14
|
+
module Cachier
|
15
|
+
module ControllerHelper
|
16
|
+
def self.included(klass)
|
17
|
+
klass.class_eval do
|
18
|
+
def write_fragment_with_tagged_key(key, content, options = nil)
|
19
|
+
if options && options[:tag] && Cachier.perform_caching?
|
20
|
+
tags = case options[:tag].class.to_s
|
21
|
+
when 'Proc', 'Lambda'
|
22
|
+
options[:tag].call(self)
|
23
|
+
else
|
24
|
+
options[:tag]
|
25
|
+
end
|
26
|
+
Cachier.store_fragment fragment_cache_key(key), *tags
|
27
|
+
end
|
28
|
+
write_fragment_without_tagged_key(key, content, options)
|
29
|
+
end
|
30
|
+
alias_method_chain :write_fragment, :tagged_key
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Cachier
|
2
|
+
module Matchers
|
3
|
+
|
4
|
+
def be_cached
|
5
|
+
Cache.new
|
6
|
+
end
|
7
|
+
|
8
|
+
class Cache
|
9
|
+
def matches?(target)
|
10
|
+
@target = target
|
11
|
+
|
12
|
+
@test_results = Cachier.keys_for(@target).inject({}) do |hash, key|
|
13
|
+
hash.merge(key => Rails.cache.exist?(key))
|
14
|
+
end
|
15
|
+
|
16
|
+
flag = @test_results.values.inject(true) { |f, v| f && v }
|
17
|
+
flag && Cachier.keys_for(@target).present?
|
18
|
+
end
|
19
|
+
|
20
|
+
def failure_message_for_should
|
21
|
+
<<-msg
|
22
|
+
expected the Rails.cache to include all these keys:
|
23
|
+
#{Cachier.keys_for(@target).to_sentence}, but
|
24
|
+
it did not include these keys:
|
25
|
+
#{@test_results.keys.select {|k| @test_results[k] == false }.to_sentence}
|
26
|
+
msg
|
27
|
+
end
|
28
|
+
|
29
|
+
def failure_message_for_should_not
|
30
|
+
<<-msg
|
31
|
+
expected the Rails.cache to not include all these keys:
|
32
|
+
#{Cachier.keys_for(@target).to_sentence}, but
|
33
|
+
it did include these keys:
|
34
|
+
#{@test_results.keys.select {|k| @test_results[k] == true }.to_sentence}
|
35
|
+
msg
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Hooks into ApplicationController's write_fragment method.
|
2
|
+
# write_fragment is used for action and fragment caching.
|
3
|
+
# Create an alias method chain to call our customer method
|
4
|
+
# which stores the associated key with the tag in a
|
5
|
+
# Redis Set. Then we can expire all those keys from anywhere
|
6
|
+
# in the code using Rails.cache.delete
|
7
|
+
#
|
8
|
+
# I use alias_method_chain instead of calling 'super'
|
9
|
+
# because there is a very rare case where someone
|
10
|
+
# may have redfined 'write_fragment' in their own
|
11
|
+
# controllers. Using an alias method chain
|
12
|
+
# keeps those methods intact.
|
13
|
+
|
14
|
+
module Cashier
|
15
|
+
module ControllerHelper
|
16
|
+
def self.included(klass)
|
17
|
+
klass.class_eval do
|
18
|
+
def write_fragment_with_tagged_key(key, content, options = nil)
|
19
|
+
if options && options[:tag] && Cashier.perform_caching?
|
20
|
+
tags = case options[:tag].class.to_s
|
21
|
+
when 'Proc', 'Lambda'
|
22
|
+
options[:tag].call(self)
|
23
|
+
else
|
24
|
+
options[:tag]
|
25
|
+
end
|
26
|
+
Cashier.store_fragment fragment_cache_key(key), *tags
|
27
|
+
end
|
28
|
+
write_fragment_without_tagged_key(key, content, options)
|
29
|
+
end
|
30
|
+
alias_method_chain :write_fragment, :tagged_key
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/cucumber.rb
ADDED
data/lib/matchers.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
module Cashier
|
2
|
+
module Matchers
|
3
|
+
|
4
|
+
def be_cached
|
5
|
+
Cache.new
|
6
|
+
end
|
7
|
+
|
8
|
+
class Cache
|
9
|
+
def matches?(target)
|
10
|
+
@target = target
|
11
|
+
|
12
|
+
@test_results = Cashier.keys_for(@target).inject({}) do |hash, key|
|
13
|
+
hash.merge(key => Rails.cache.exist?(key))
|
14
|
+
end
|
15
|
+
|
16
|
+
flag = @test_results.values.inject(true) { |f, v| f && v }
|
17
|
+
flag && Cashier.keys_for(@target).present?
|
18
|
+
end
|
19
|
+
|
20
|
+
def failure_message_for_should
|
21
|
+
<<-msg
|
22
|
+
expected the Rails.cache to include all these keys:
|
23
|
+
#{Cashier.keys_for(@target).to_sentence}, but
|
24
|
+
it did not include these keys:
|
25
|
+
#{@test_results.keys.select {|k| @test_results[k] == false }.to_sentence}
|
26
|
+
msg
|
27
|
+
end
|
28
|
+
|
29
|
+
def failure_message_for_should_not
|
30
|
+
<<-msg
|
31
|
+
expected the Rails.cache to not include all these keys:
|
32
|
+
#{Cashier.keys_for(@target).to_sentence}, but
|
33
|
+
it did include these keys:
|
34
|
+
#{@test_results.keys.select {|k| @test_results[k] == true }.to_sentence}
|
35
|
+
msg
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/railtie.rb
ADDED
data/lib/version.rb
ADDED
metadata
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cachier
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Avi Tzurel
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-10-19 00:00:00 -07:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rspec
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: hiredis
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id002
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: redis
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 3
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
version: "0"
|
61
|
+
type: :development
|
62
|
+
version_requirements: *id003
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: redis-namespace
|
65
|
+
prerelease: false
|
66
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
hash: 3
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
version: "0"
|
75
|
+
type: :development
|
76
|
+
version_requirements: *id004
|
77
|
+
description: Tag your cache keys smartly, you can expire by tags, count keys per tag and many more. based on Redis
|
78
|
+
email: avi@kensodev.com
|
79
|
+
executables: []
|
80
|
+
|
81
|
+
extensions: []
|
82
|
+
|
83
|
+
extra_rdoc_files: []
|
84
|
+
|
85
|
+
files:
|
86
|
+
- lib/cachier/controller_helper.rb
|
87
|
+
- lib/cachier/cucumber.rb
|
88
|
+
- lib/cachier/matchers.rb
|
89
|
+
- lib/cachier/version.rb
|
90
|
+
- lib/cachier.rb
|
91
|
+
- lib/controller_helper.rb
|
92
|
+
- lib/cucumber.rb
|
93
|
+
- lib/matchers.rb
|
94
|
+
- lib/railtie.rb
|
95
|
+
- lib/version.rb
|
96
|
+
has_rdoc: true
|
97
|
+
homepage: https://github.com/KensoDev/cachier
|
98
|
+
licenses: []
|
99
|
+
|
100
|
+
post_install_message:
|
101
|
+
rdoc_options: []
|
102
|
+
|
103
|
+
require_paths:
|
104
|
+
- .
|
105
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
hash: 3
|
111
|
+
segments:
|
112
|
+
- 0
|
113
|
+
version: "0"
|
114
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
|
+
none: false
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
hash: 3
|
120
|
+
segments:
|
121
|
+
- 0
|
122
|
+
version: "0"
|
123
|
+
requirements: []
|
124
|
+
|
125
|
+
rubyforge_project:
|
126
|
+
rubygems_version: 1.3.7
|
127
|
+
signing_key:
|
128
|
+
specification_version: 3
|
129
|
+
summary: Tagging ability for your cache keys, based on Redis
|
130
|
+
test_files: []
|
131
|
+
|