garner 0.3.3 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.md +1 -1
- data/README.md +116 -135
- data/lib/garner/cache/binding.rb +58 -0
- data/lib/garner/cache/context.rb +27 -0
- data/lib/garner/cache/identity.rb +45 -0
- data/lib/garner/cache.rb +41 -0
- data/lib/garner/config.rb +46 -15
- data/lib/garner/mixins/mongoid/document.rb +75 -0
- data/lib/garner/mixins/mongoid/identity.rb +106 -0
- data/lib/garner/mixins/mongoid.rb +4 -0
- data/lib/garner/mixins/rack.rb +45 -0
- data/lib/garner/strategies/binding/invalidation/base.rb +26 -0
- data/lib/garner/strategies/binding/invalidation/touch.rb +27 -0
- data/lib/garner/strategies/binding/key/base.rb +19 -0
- data/lib/garner/strategies/binding/key/cache_key.rb +19 -0
- data/lib/garner/strategies/binding/key/safe_cache_key.rb +33 -0
- data/lib/garner/strategies/context/key/base.rb +21 -0
- data/lib/garner/strategies/context/key/caller.rb +83 -0
- data/lib/garner/strategies/context/key/jsonp.rb +30 -0
- data/lib/garner/strategies/context/key/request_get.rb +30 -0
- data/lib/garner/strategies/context/key/request_path.rb +28 -0
- data/lib/garner/strategies/context/key/request_post.rb +30 -0
- data/lib/garner/version.rb +1 -1
- data/lib/garner.rb +29 -26
- metadata +122 -22
- data/lib/garner/cache/object_identity.rb +0 -249
- data/lib/garner/middleware/base.rb +0 -47
- data/lib/garner/middleware/cache/bust.rb +0 -20
- data/lib/garner/mixins/grape_cache.rb +0 -111
- data/lib/garner/mixins/mongoid_document.rb +0 -58
- data/lib/garner/strategies/cache/expiration_strategy.rb +0 -16
- data/lib/garner/strategies/etags/grape_strategy.rb +0 -32
- data/lib/garner/strategies/etags/marshal_strategy.rb +0 -16
- data/lib/garner/strategies/keys/caller_strategy.rb +0 -38
- data/lib/garner/strategies/keys/jsonp_strategy.rb +0 -24
- data/lib/garner/strategies/keys/key_strategy.rb +0 -21
- data/lib/garner/strategies/keys/request_get_strategy.rb +0 -24
- data/lib/garner/strategies/keys/request_path_strategy.rb +0 -21
- data/lib/garner/strategies/keys/request_post_strategy.rb +0 -24
- data/lib/garner/strategies/keys/version_strategy.rb +0 -29
@@ -0,0 +1,75 @@
|
|
1
|
+
# Set up Garner configuration parameters
|
2
|
+
Garner.config.option(:mongoid_binding_key_strategy, {
|
3
|
+
:default => Garner.config.binding_key_strategy
|
4
|
+
})
|
5
|
+
|
6
|
+
Garner.config.option(:mongoid_binding_invalidation_strategy, {
|
7
|
+
:default => Garner.config.binding_invalidation_strategy
|
8
|
+
})
|
9
|
+
|
10
|
+
module Garner
|
11
|
+
module Mixins
|
12
|
+
module Mongoid
|
13
|
+
module Document
|
14
|
+
extend ActiveSupport::Concern
|
15
|
+
include Garner::Cache::Binding
|
16
|
+
|
17
|
+
def key_strategy
|
18
|
+
Garner.config.mongoid_binding_key_strategy
|
19
|
+
end
|
20
|
+
|
21
|
+
def invalidation_strategy
|
22
|
+
Garner.config.mongoid_binding_invalidation_strategy
|
23
|
+
end
|
24
|
+
|
25
|
+
included do
|
26
|
+
extend Garner::Cache::Binding
|
27
|
+
|
28
|
+
def self.cache_key
|
29
|
+
_latest_by_updated_at.try(:cache_key)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.touch
|
33
|
+
_latest_by_updated_at.try(:touch)
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.updated_at
|
37
|
+
_latest_by_updated_at.try(:updated_at)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.key_strategy
|
41
|
+
Garner.config.mongoid_binding_key_strategy
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.invalidation_strategy
|
45
|
+
Garner.config.mongoid_binding_invalidation_strategy
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.identify(id)
|
49
|
+
Garner::Mixins::Mongoid::Identity.from_class_and_id(self, id)
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.garnered_find(id)
|
53
|
+
return nil unless (binding = identify(id))
|
54
|
+
identity = Garner::Cache::Identity.new
|
55
|
+
identity.bind(binding).key({ :source => :garnered_find }) { find(id) }
|
56
|
+
end
|
57
|
+
|
58
|
+
after_create :_garner_after_create
|
59
|
+
after_update :_garner_after_update
|
60
|
+
after_destroy :_garner_after_destroy
|
61
|
+
|
62
|
+
protected
|
63
|
+
def self._latest_by_updated_at
|
64
|
+
# Only find the latest if we can order by :updated_at
|
65
|
+
return nil unless fields["updated_at"]
|
66
|
+
only(:_id, :_type, :updated_at).order_by({
|
67
|
+
:updated_at => :desc
|
68
|
+
}).first
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# Set up Garner configuration parameters
|
2
|
+
Garner.config.option(:mongoid_identity_fields, {
|
3
|
+
:default => [:_id]
|
4
|
+
})
|
5
|
+
|
6
|
+
module Garner
|
7
|
+
module Mixins
|
8
|
+
module Mongoid
|
9
|
+
class Identity
|
10
|
+
include Garner::Cache::Binding
|
11
|
+
|
12
|
+
attr_accessor :document, :collection_name, :conditions
|
13
|
+
|
14
|
+
def self.from_class_and_id(klass, id)
|
15
|
+
validate_class!(klass)
|
16
|
+
|
17
|
+
self.new.tap do |identity|
|
18
|
+
identity.collection_name = klass.collection_name
|
19
|
+
identity.conditions = conditions_for(klass, id)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize
|
24
|
+
@conditions = {}
|
25
|
+
end
|
26
|
+
|
27
|
+
def key_strategy
|
28
|
+
Garner.config.mongoid_binding_key_strategy
|
29
|
+
end
|
30
|
+
|
31
|
+
def invalidation_strategy
|
32
|
+
Garner.config.mongoid_binding_invalidation_strategy
|
33
|
+
end
|
34
|
+
|
35
|
+
def cache_key
|
36
|
+
# See https://github.com/mongoid/mongoid/blob/f5ba1295/lib/mongoid/document.rb#L242
|
37
|
+
if updated_at
|
38
|
+
"#{model_cache_key}/#{_id}-#{updated_at.utc.to_s(:number)}"
|
39
|
+
elsif _id
|
40
|
+
"#{model_cache_key}/#{_id}"
|
41
|
+
else
|
42
|
+
"#{model_cache_key}/new"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def model_cache_key
|
47
|
+
if _type
|
48
|
+
ActiveModel::Name.new(_type.constantize).cache_key
|
49
|
+
else
|
50
|
+
@collection_name.to_s
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def collection
|
55
|
+
::Mongoid.default_session[@collection_name]
|
56
|
+
end
|
57
|
+
|
58
|
+
def document
|
59
|
+
return @document if @document
|
60
|
+
|
61
|
+
collection.where(@conditions).select({
|
62
|
+
:_id => 1,
|
63
|
+
:_type => 1,
|
64
|
+
:updated_at => 1
|
65
|
+
}).limit(1).first
|
66
|
+
end
|
67
|
+
|
68
|
+
def _id
|
69
|
+
document["_id"] if document
|
70
|
+
end
|
71
|
+
|
72
|
+
def updated_at
|
73
|
+
document["updated_at"] if document
|
74
|
+
end
|
75
|
+
|
76
|
+
def _type
|
77
|
+
document["_type"] if document
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
def self.validate_class!(klass)
|
82
|
+
if !klass.include?(::Mongoid::Document)
|
83
|
+
raise "Must instantiate from a Mongoid class"
|
84
|
+
elsif klass.embedded?
|
85
|
+
raise "Cannot instantiate from an embedded document class"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.conditions_for(klass, id)
|
90
|
+
# multiple-ID conditions
|
91
|
+
conditions = {
|
92
|
+
"$or" => Garner.config.mongoid_identity_fields.map { |field|
|
93
|
+
{ field => id }
|
94
|
+
}
|
95
|
+
}
|
96
|
+
|
97
|
+
# _type conditions
|
98
|
+
selector = klass.where({})
|
99
|
+
conditions.merge!(selector.send(:type_selection)) if selector.send(:type_selectable?)
|
100
|
+
|
101
|
+
conditions
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require "garner"
|
2
|
+
|
3
|
+
# Set up Garner configuration parameters
|
4
|
+
Garner.config.option(:rack_context_key_strategies, {
|
5
|
+
:default => [
|
6
|
+
Garner::Strategies::Context::Key::Caller,
|
7
|
+
Garner::Strategies::Context::Key::RequestGet,
|
8
|
+
Garner::Strategies::Context::Key::RequestPost,
|
9
|
+
Garner::Strategies::Context::Key::RequestPath
|
10
|
+
]
|
11
|
+
})
|
12
|
+
|
13
|
+
module Garner
|
14
|
+
module Mixins
|
15
|
+
module Rack
|
16
|
+
|
17
|
+
# Override this method to conditionally disable the cache.
|
18
|
+
#
|
19
|
+
# @return [Boolean]
|
20
|
+
def cache_enabled?
|
21
|
+
true
|
22
|
+
end
|
23
|
+
|
24
|
+
# Instantiate a context-appropriate cache identity.
|
25
|
+
#
|
26
|
+
# @example
|
27
|
+
# garner.bind(current_user) do
|
28
|
+
# { count: current_user.logins.count }
|
29
|
+
# end
|
30
|
+
# @return [Garner::Cache::Identity] The cache identity.
|
31
|
+
def garner(&block)
|
32
|
+
identity = Garner::Cache::Identity.new
|
33
|
+
Garner.config.rack_context_key_strategies.each do |strategy|
|
34
|
+
identity = strategy.apply(identity, self)
|
35
|
+
end
|
36
|
+
|
37
|
+
unless cache_enabled?
|
38
|
+
identity.options({ :force_miss => true })
|
39
|
+
end
|
40
|
+
|
41
|
+
block_given? ? identity.fetch(&block) : identity
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Garner
|
2
|
+
module Strategies
|
3
|
+
module Binding
|
4
|
+
module Invalidation
|
5
|
+
class Base
|
6
|
+
|
7
|
+
# Specifies whether invalidation should happen on callbacks.
|
8
|
+
#
|
9
|
+
# @param kind [Symbol] One of :create, :update, :destroy
|
10
|
+
def self.apply_on_callback?(kind = nil)
|
11
|
+
true
|
12
|
+
end
|
13
|
+
|
14
|
+
# Force-invalidate an object binding. Used when bindings are
|
15
|
+
# explicitly invalidated, via binding.invalidate_garner_caches.
|
16
|
+
#
|
17
|
+
# @param binding [Object] The binding whose caches are to be
|
18
|
+
# invalidated.
|
19
|
+
def self.apply(binding)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Garner
|
2
|
+
module Strategies
|
3
|
+
module Binding
|
4
|
+
module Invalidation
|
5
|
+
class Touch < Base
|
6
|
+
|
7
|
+
# Specifies whether invalidation should happen on callbacks.
|
8
|
+
#
|
9
|
+
# @param kind [Symbol] One of :create, :update, :destroy
|
10
|
+
def self.apply_on_callback?(kind = nil)
|
11
|
+
false
|
12
|
+
end
|
13
|
+
|
14
|
+
# Force-invalidate an object binding. Used when bindings are
|
15
|
+
# explicitly invalidated, via binding.invalidate_garner_caches.
|
16
|
+
#
|
17
|
+
# @param binding [Object] The binding whose caches are to be
|
18
|
+
# invalidated.
|
19
|
+
def self.apply(binding)
|
20
|
+
binding.touch if binding.respond_to?(:touch)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Garner
|
2
|
+
module Strategies
|
3
|
+
module Binding
|
4
|
+
module Key
|
5
|
+
class Base
|
6
|
+
|
7
|
+
# Compute a cache key from an object binding.
|
8
|
+
#
|
9
|
+
# @param binding [Object] The object from which to compute a key.
|
10
|
+
# @return [String] A cache key string.
|
11
|
+
def self.apply(binding)
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Garner
|
2
|
+
module Strategies
|
3
|
+
module Binding
|
4
|
+
module Key
|
5
|
+
class CacheKey < Base
|
6
|
+
|
7
|
+
# Compute a cache key from an object binding.
|
8
|
+
#
|
9
|
+
# @param binding [Object] The object from which to compute a key.
|
10
|
+
# @return [String] A cache key string.
|
11
|
+
def self.apply(binding)
|
12
|
+
binding.cache_key if binding.respond_to?(:cache_key)
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Garner
|
2
|
+
module Strategies
|
3
|
+
module Binding
|
4
|
+
module Key
|
5
|
+
class SafeCacheKey < Base
|
6
|
+
VALID_FORMAT = /^(?<model>[^\/]+)\/(?<id>.+)-(?<timestamp>[0-9]{14})$/
|
7
|
+
|
8
|
+
# Compute a cache key from an object binding. Only return a key if
|
9
|
+
# :cache_key and :updated_at are both defined and present on the
|
10
|
+
# object, and if :cache_key conforms to the ActiveModel format.
|
11
|
+
#
|
12
|
+
# If all requirements are met, append the millisecond portion of
|
13
|
+
# :updated_at to :cache_key.
|
14
|
+
#
|
15
|
+
# @param binding [Object] The object from which to compute a key.
|
16
|
+
# @return [String] A cache key string.
|
17
|
+
def self.apply(binding)
|
18
|
+
return unless binding.respond_to?(:cache_key) && binding.cache_key
|
19
|
+
return unless binding.respond_to?(:updated_at) && binding.updated_at
|
20
|
+
|
21
|
+
# Check for ActiveModel cache key format
|
22
|
+
return unless binding.cache_key =~ VALID_FORMAT
|
23
|
+
|
24
|
+
decimal_portion = binding.updated_at.utc.to_f % 1
|
25
|
+
decimal_string = sprintf("%.10f", decimal_portion).gsub(/^0/, "")
|
26
|
+
"#{binding.cache_key}#{decimal_string}"
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Garner
|
2
|
+
module Strategies
|
3
|
+
module Context
|
4
|
+
module Key
|
5
|
+
class Base
|
6
|
+
|
7
|
+
# Compute a hash of key-value pairs from a given ruby context,
|
8
|
+
# and apply it to a cache identity.
|
9
|
+
#
|
10
|
+
# @param identity [Garner::Cache::Identity] The cache identity.
|
11
|
+
# @param ruby_context [Object] An optional Ruby context.
|
12
|
+
# @return [Garner::Cache::Identity] The modified identity.
|
13
|
+
def self.apply(identity, ruby_context = self)
|
14
|
+
identity
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Garner
|
2
|
+
module Strategies
|
3
|
+
module Context
|
4
|
+
module Key
|
5
|
+
class Caller < Base
|
6
|
+
|
7
|
+
def self.field
|
8
|
+
:caller
|
9
|
+
end
|
10
|
+
|
11
|
+
# Determine the most likely root path for the current Garner client
|
12
|
+
# application. If in a Rails application, Rails.root is used.
|
13
|
+
# Otherwise, the nearest ancestor directory containing a Gemfile is
|
14
|
+
# used.
|
15
|
+
#
|
16
|
+
# @see Garner::Config#caller_root=
|
17
|
+
# @see Garner::Config#default_caller_root
|
18
|
+
# @return [String] The default root path.
|
19
|
+
def self.default_root
|
20
|
+
if defined?(::Rails) && ::Rails.respond_to?(:root)
|
21
|
+
::Rails.root
|
22
|
+
else
|
23
|
+
# Try to use the nearest ancestor directory containing a Gemfile.
|
24
|
+
requiring_caller = send(:caller).detect do |line|
|
25
|
+
!line.include?(File.join("lib", "garner"))
|
26
|
+
end
|
27
|
+
return nil unless requiring_caller
|
28
|
+
|
29
|
+
requiring_file = requiring_caller.split(":")[0]
|
30
|
+
gemfile_root(File.dirname(requiring_file))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Injects the caller's location into the key hash.
|
35
|
+
#
|
36
|
+
# @param identity [Garner::Cache::Identity] The cache identity.
|
37
|
+
# @param ruby_context [Object] An optional Ruby context.
|
38
|
+
# @return [Garner::Cache::Identity] The modified identity.
|
39
|
+
def self.apply(identity, ruby_context = self)
|
40
|
+
value = nil
|
41
|
+
|
42
|
+
if ruby_context.send(:caller)
|
43
|
+
ruby_context.send(:caller).compact.each do |line|
|
44
|
+
parts = line.match(/(?<filename>[^:]+)\:(?<lineno>[^:]+)/)
|
45
|
+
file = (Pathname.new(parts[:filename]).realpath.to_s rescue nil)
|
46
|
+
next if file.nil? || file == ""
|
47
|
+
next if file.include?(File.join("lib", "garner"))
|
48
|
+
|
49
|
+
if (root = Garner.config.caller_root)
|
50
|
+
root += File::SEPARATOR unless root[-1] == File::SEPARATOR
|
51
|
+
next unless file =~ /^#{root}/
|
52
|
+
value = "#{file.gsub(root || "", "")}:#{parts[:lineno]}"
|
53
|
+
else
|
54
|
+
value = "#{file}:#{parts[:lineno]}"
|
55
|
+
end
|
56
|
+
|
57
|
+
break
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
value ? identity.key(field => value) : identity
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
def self.gemfile_root(path)
|
66
|
+
path = Pathname.new(path).realpath.to_s
|
67
|
+
newpath = Pathname.new(File.join(path, "..")).realpath.to_s
|
68
|
+
if newpath == path
|
69
|
+
# We've reached the filesystem root; return
|
70
|
+
return nil
|
71
|
+
elsif File.exist?(File.join(newpath, "Gemfile"))
|
72
|
+
# We've struck Gemfile gold; return current path
|
73
|
+
return newpath
|
74
|
+
else
|
75
|
+
return gemfile_root(newpath)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Garner
|
2
|
+
module Strategies
|
3
|
+
module Context
|
4
|
+
module Key
|
5
|
+
class Jsonp < Base
|
6
|
+
|
7
|
+
def self.field
|
8
|
+
:request_params
|
9
|
+
end
|
10
|
+
|
11
|
+
# Strips JSONP parameters from the key.
|
12
|
+
#
|
13
|
+
# @param identity [Garner::Cache::Identity] The cache identity.
|
14
|
+
# @param ruby_context [Object] An optional Ruby context.
|
15
|
+
# @return [Garner::Cache::Identity] The modified identity.
|
16
|
+
def self.apply(identity, ruby_context = self)
|
17
|
+
key_hash = identity.key_hash
|
18
|
+
return identity unless key_hash[field]
|
19
|
+
|
20
|
+
|
21
|
+
key_hash[field].delete("callback")
|
22
|
+
key_hash[field].delete("_")
|
23
|
+
identity
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Garner
|
2
|
+
module Strategies
|
3
|
+
module Context
|
4
|
+
module Key
|
5
|
+
class RequestGet < Base
|
6
|
+
|
7
|
+
def self.field
|
8
|
+
:request_params
|
9
|
+
end
|
10
|
+
|
11
|
+
# Injects the request GET parameters into the key hash.
|
12
|
+
#
|
13
|
+
# @param identity [Garner::Cache::Identity] The cache identity.
|
14
|
+
# @param ruby_context [Object] An optional Ruby context.
|
15
|
+
# @return [Garner::Cache::Identity] The modified identity.
|
16
|
+
def self.apply(identity, ruby_context = self)
|
17
|
+
return identity unless (ruby_context.respond_to?(:request))
|
18
|
+
|
19
|
+
request = ruby_context.request
|
20
|
+
if request && ["GET", "HEAD"].include?(request.request_method)
|
21
|
+
identity.key(field => request.GET.dup)
|
22
|
+
end
|
23
|
+
identity
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Garner
|
2
|
+
module Strategies
|
3
|
+
module Context
|
4
|
+
module Key
|
5
|
+
class RequestPath < Base
|
6
|
+
|
7
|
+
def self.field
|
8
|
+
:request_path
|
9
|
+
end
|
10
|
+
|
11
|
+
# Injects the request path into the key hash.
|
12
|
+
#
|
13
|
+
# @param identity [Garner::Cache::Identity] The cache identity.
|
14
|
+
# @param ruby_context [Object] An optional Ruby context.
|
15
|
+
# @return [Garner::Cache::Identity] The modified identity.
|
16
|
+
def self.apply(identity, ruby_context = self)
|
17
|
+
return identity unless (ruby_context.respond_to?(:request))
|
18
|
+
|
19
|
+
request = ruby_context.request
|
20
|
+
identity.key(field => request.path) if request.respond_to?(:path)
|
21
|
+
identity
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Garner
|
2
|
+
module Strategies
|
3
|
+
module Context
|
4
|
+
module Key
|
5
|
+
class RequestPost < Base
|
6
|
+
|
7
|
+
def self.field
|
8
|
+
:request_params
|
9
|
+
end
|
10
|
+
|
11
|
+
# Injects the request POST parameters into the key hash.
|
12
|
+
#
|
13
|
+
# @param identity [Garner::Cache::Identity] The cache identity.
|
14
|
+
# @param ruby_context [Object] An optional Ruby context.
|
15
|
+
# @return [Garner::Cache::Identity] The modified identity.
|
16
|
+
def self.apply(identity, ruby_context = self)
|
17
|
+
return identity unless (ruby_context.respond_to?(:request))
|
18
|
+
|
19
|
+
request = ruby_context.request
|
20
|
+
if request.request_method == "POST"
|
21
|
+
identity = identity.key(field => request.POST.dup)
|
22
|
+
end
|
23
|
+
identity
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/garner/version.rb
CHANGED
data/lib/garner.rb
CHANGED
@@ -1,26 +1,29 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
|
4
|
-
|
5
|
-
require
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
require
|
19
|
-
require
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
require
|
24
|
-
|
25
|
-
|
26
|
-
require
|
1
|
+
require "multi_json"
|
2
|
+
require "active_support"
|
3
|
+
|
4
|
+
# Garner core
|
5
|
+
require "garner/version"
|
6
|
+
require "garner/config"
|
7
|
+
|
8
|
+
# Key strategies
|
9
|
+
require "garner/strategies/context/key/base"
|
10
|
+
require "garner/strategies/context/key/caller"
|
11
|
+
require "garner/strategies/context/key/request_path"
|
12
|
+
require "garner/strategies/context/key/request_get"
|
13
|
+
require "garner/strategies/context/key/request_post"
|
14
|
+
require "garner/strategies/context/key/jsonp"
|
15
|
+
|
16
|
+
# Binding strategies
|
17
|
+
require "garner/strategies/binding/key/base"
|
18
|
+
require "garner/strategies/binding/key/cache_key"
|
19
|
+
require "garner/strategies/binding/key/safe_cache_key"
|
20
|
+
|
21
|
+
# Invalidation strategies
|
22
|
+
require "garner/strategies/binding/invalidation/base"
|
23
|
+
require "garner/strategies/binding/invalidation/touch"
|
24
|
+
|
25
|
+
# Cache
|
26
|
+
require "garner/cache"
|
27
|
+
require "garner/cache/identity"
|
28
|
+
require "garner/cache/context"
|
29
|
+
require "garner/cache/binding"
|