caching_with_tags 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/.gitignore +4 -0
- data/Gemfile +3 -0
- data/Rakefile +1 -0
- data/caching_with_tags.gemspec +21 -0
- data/lib/caching_with_tags.rb +6 -0
- data/lib/caching_with_tags/railtie.rb +8 -0
- data/lib/caching_with_tags/store.rb +135 -0
- data/lib/caching_with_tags/version.rb +3 -0
- metadata +64 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,21 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
require "caching_with_tags/version"
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "caching_with_tags"
|
6
|
+
s.version = CachingWithTags::VERSION
|
7
|
+
s.authors = ["Vitaly Tsevan"]
|
8
|
+
s.email = ["vzevan@gmail.com"]
|
9
|
+
s.homepage = ""
|
10
|
+
s.summary = %q{Realisation of cache tagging for rails}
|
11
|
+
s.description = %q{Realisation of cache tagging for rails}
|
12
|
+
|
13
|
+
s.files = `git ls-files`.split("\n")
|
14
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
15
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
|
18
|
+
# specify any dependencies here; for example:
|
19
|
+
# s.add_development_dependency "rspec"
|
20
|
+
s.add_runtime_dependency "rails"
|
21
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
class Railtie < ::Rails::Railtie
|
2
|
+
initializer 'caching_with_tags.on_rails_init' do
|
3
|
+
ActiveSupport.on_load :before_configuration do
|
4
|
+
ActiveSupport.send :include, CachingWithTags::StoreMethods
|
5
|
+
ActiveSupport.send :include, CachingWithTags::EntryMethods
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
module CachingWithTags
|
2
|
+
module StoreMethods
|
3
|
+
class ActiveSupport::Cache::Store
|
4
|
+
def read(name, options = nil)
|
5
|
+
options = merged_options(options)
|
6
|
+
key = namespaced_key(name, options)
|
7
|
+
instrument(:read, name, options) do |payload|
|
8
|
+
########patched
|
9
|
+
entry = read_entry(key, options)
|
10
|
+
entry = nil if entry && entry.tags && !tags_actual?(entry.tags)
|
11
|
+
#######patch end
|
12
|
+
|
13
|
+
if entry
|
14
|
+
if entry.expired?
|
15
|
+
delete_entry(key, options)
|
16
|
+
payload[:hit] = false if payload
|
17
|
+
nil
|
18
|
+
else
|
19
|
+
payload[:hit] = true if payload
|
20
|
+
entry.value
|
21
|
+
end
|
22
|
+
else
|
23
|
+
payload[:hit] = false if payload
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def fetch(name, options = nil)
|
30
|
+
if block_given?
|
31
|
+
options = merged_options(options)
|
32
|
+
key = namespaced_key(name, options)
|
33
|
+
########patched
|
34
|
+
unless options[:force]
|
35
|
+
entry = instrument(:read, name, options) do |payload|
|
36
|
+
payload[:super_operation] = :fetch if payload
|
37
|
+
ent = read_entry(key, options)
|
38
|
+
ent = nil if ent && ent.tags && !tags_actual?(ent.tags)
|
39
|
+
ent
|
40
|
+
end
|
41
|
+
end
|
42
|
+
########end of patch
|
43
|
+
if entry && entry.expired?
|
44
|
+
race_ttl = options[:race_condition_ttl].to_f
|
45
|
+
if race_ttl and Time.now.to_f - entry.expires_at <= race_ttl
|
46
|
+
entry.expires_at = Time.now + race_ttl
|
47
|
+
write_entry(key, entry, :expires_in => race_ttl * 2)
|
48
|
+
else
|
49
|
+
delete_entry(key, options)
|
50
|
+
end
|
51
|
+
entry = nil
|
52
|
+
end
|
53
|
+
|
54
|
+
if entry
|
55
|
+
instrument(:fetch_hit, name, options) { |payload| }
|
56
|
+
entry.value
|
57
|
+
else
|
58
|
+
result = instrument(:generate, name, options) do |payload|
|
59
|
+
yield
|
60
|
+
end
|
61
|
+
write(name, result, options)
|
62
|
+
result
|
63
|
+
end
|
64
|
+
else
|
65
|
+
read(name, options)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def write(name, value, options = nil)
|
70
|
+
options = merged_options(options)
|
71
|
+
instrument(:write, name, options) do |payload|
|
72
|
+
######patch
|
73
|
+
entry = ActiveSupport::Cache::Entry.new(value, options)
|
74
|
+
write_meta(entry, options[:tags]) if options[:tags]
|
75
|
+
write_entry(namespaced_key(name, options), entry, options)
|
76
|
+
######end of patch
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def exist?(name, options = nil)
|
81
|
+
options = merged_options(options)
|
82
|
+
instrument(:exist?, name) do |payload|
|
83
|
+
#####patched
|
84
|
+
entry = read_entry(namespaced_key(name, options), options)
|
85
|
+
entry = nil if entry && entry.tags && !tags_actual?(entry.tags)
|
86
|
+
#####end of patch
|
87
|
+
if entry && !entry.expired?
|
88
|
+
true
|
89
|
+
else
|
90
|
+
false
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
#####patch
|
96
|
+
|
97
|
+
def write_meta(entry, tags)
|
98
|
+
t = if tags.is_a?(Array)
|
99
|
+
tags.inject({}) do |res, el|
|
100
|
+
res[el] = fetch(el, {:namespace => nil}) { 1 }
|
101
|
+
res
|
102
|
+
end
|
103
|
+
end
|
104
|
+
entry.tags = t
|
105
|
+
end
|
106
|
+
|
107
|
+
def tags_actual?(tags)
|
108
|
+
if tags.is_a?(Hash)
|
109
|
+
# We're doing dup here because of Dalli makes force_encoding
|
110
|
+
# and ActiveSupport returns frozen values, so it raises an exception.
|
111
|
+
# Ruby uses copy-on-write technique so it's extremely cheap to make a dup
|
112
|
+
# of all tags.keys as far as we don't modify them
|
113
|
+
actual_versions = read_multi(*tags.keys.map { |k| k.dup } << {:namespace => nil})
|
114
|
+
actual_versions == tags
|
115
|
+
else
|
116
|
+
false
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def increment_tag(name, options = nil)
|
121
|
+
options = merged_options(options)
|
122
|
+
entry = read_entry(namespaced_key(name, {:namespace => nil}), options)
|
123
|
+
value = entry ? entry.value + 1 : 1
|
124
|
+
write_entry(namespaced_key(name, {:namespace => nil}), ActiveSupport::Cache::Entry.new(value), options)
|
125
|
+
end
|
126
|
+
######end of patch
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
module EntryMethods
|
131
|
+
class ActiveSupport::Cache::Entry
|
132
|
+
attr_accessor :tags
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: caching_with_tags
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Vitaly Tsevan
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-04-08 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rails
|
16
|
+
requirement: &12632800 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *12632800
|
25
|
+
description: Realisation of cache tagging for rails
|
26
|
+
email:
|
27
|
+
- vzevan@gmail.com
|
28
|
+
executables: []
|
29
|
+
extensions: []
|
30
|
+
extra_rdoc_files: []
|
31
|
+
files:
|
32
|
+
- .gitignore
|
33
|
+
- Gemfile
|
34
|
+
- Rakefile
|
35
|
+
- caching_with_tags.gemspec
|
36
|
+
- lib/caching_with_tags.rb
|
37
|
+
- lib/caching_with_tags/railtie.rb
|
38
|
+
- lib/caching_with_tags/store.rb
|
39
|
+
- lib/caching_with_tags/version.rb
|
40
|
+
homepage: ''
|
41
|
+
licenses: []
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options: []
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
none: false
|
48
|
+
requirements:
|
49
|
+
- - ! '>='
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ! '>='
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
58
|
+
requirements: []
|
59
|
+
rubyforge_project:
|
60
|
+
rubygems_version: 1.8.10
|
61
|
+
signing_key:
|
62
|
+
specification_version: 3
|
63
|
+
summary: Realisation of cache tagging for rails
|
64
|
+
test_files: []
|