second_level_cache 2.1.16 → 2.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +4 -8
- data/Gemfile +1 -1
- data/README.md +14 -13
- data/Rakefile +2 -2
- data/lib/second_level_cache/active_record/base.rb +9 -13
- data/lib/second_level_cache/active_record/belongs_to_association.rb +8 -12
- data/lib/second_level_cache/active_record/core.rb +6 -10
- data/lib/second_level_cache/active_record/fetch_by_uniq_key.rb +29 -17
- data/lib/second_level_cache/active_record/finder_methods.rb +23 -48
- data/lib/second_level_cache/active_record/has_one_association.rb +18 -19
- data/lib/second_level_cache/active_record/persistence.rb +6 -17
- data/lib/second_level_cache/active_record/preloader.rb +16 -17
- data/lib/second_level_cache/active_record/railtie.rb +13 -10
- data/lib/second_level_cache/active_record.rb +5 -8
- data/lib/second_level_cache/config.rb +14 -15
- data/lib/second_level_cache/record_marshal.rb +20 -35
- data/lib/second_level_cache/version.rb +2 -2
- data/lib/second_level_cache.rb +18 -24
- data/second_level_cache.gemspec +19 -18
- data/test/active_record_test_case_helper.rb +15 -12
- data/test/base_test.rb +2 -3
- data/test/belongs_to_association_test.rb +2 -3
- data/test/fetch_by_uniq_key_test.rb +14 -15
- data/test/finder_methods_test.rb +5 -44
- data/test/has_one_association_test.rb +5 -10
- data/test/model/account.rb +1 -2
- data/test/model/animal.rb +0 -1
- data/test/model/book.rb +4 -5
- data/test/model/image.rb +2 -4
- data/test/model/post.rb +3 -4
- data/test/model/topic.rb +2 -3
- data/test/model/user.rb +11 -14
- data/test/persistence_test.rb +3 -4
- data/test/polymorphic_association_test.rb +1 -2
- data/test/preloader_test.rb +2 -3
- data/test/record_marshal_test.rb +12 -15
- data/test/require_test.rb +2 -3
- data/test/second_level_cache_test.rb +2 -3
- data/test/single_table_inheritance_test.rb +0 -1
- data/test/test_helper.rb +13 -13
- metadata +49 -37
- data/lib/second_level_cache/active_record/multi_read_from_cache.rb +0 -21
- data/test/model/multi_read_from_cache_test.rb +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 08afc3105b0fd6181f8c5fa0deeed4c6af159e48
|
4
|
+
data.tar.gz: 591668829c848cd26c9c7ca7ecb7edda0a5378ad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c913f07951f4c923a33580ea6576e03ba4cc30ade72ac4451adaf1b82690e3ffd3f1879ac6fd3f645ea5ec6142b3ec9e52992ecabfb650a89f76e609116cd323
|
7
|
+
data.tar.gz: cbf1edab3ddabb33d5f3a12f234ee29657d232985df41018aaecbcd2aeb614be09536b5e93c6f8ba0fbd16928cadcbaa2d771c7680411ef7e8c904ddf7f2aa3d
|
data/CHANGELOG.md
CHANGED
@@ -1,13 +1,9 @@
|
|
1
|
-
2.1
|
2
|
-
|
3
|
-
|
4
|
-
2.1.14
|
5
|
-
* support has_one with scope
|
1
|
+
2.2.1
|
2
|
+
-----
|
6
3
|
|
7
|
-
2.1.
|
8
|
-
*
|
4
|
+
* ActiveRecord 5 ready! Do not support ActiveRecord 4 and lower versions now (use second_level_cache 2.1.x).
|
5
|
+
* Requirement Ruby 2.3+.
|
9
6
|
|
10
|
-
-----
|
11
7
|
2.0.0.rc1
|
12
8
|
-----
|
13
9
|
* ActiveRecord 4 ready!
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -16,6 +16,14 @@ Write-Through: As objects are created, updated, and deleted, all of the caches a
|
|
16
16
|
|
17
17
|
In your gem file:
|
18
18
|
|
19
|
+
ActiveRecord 5:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
gem 'second_level_cache', '~> 2.2.0'
|
23
|
+
```
|
24
|
+
|
25
|
+
For ActiveRecord 4:
|
26
|
+
|
19
27
|
```ruby
|
20
28
|
gem "second_level_cache", "~> 2.1.9"
|
21
29
|
```
|
@@ -32,7 +40,7 @@ For example, cache User objects:
|
|
32
40
|
|
33
41
|
```ruby
|
34
42
|
class User < ActiveRecord::Base
|
35
|
-
acts_as_cached(:
|
43
|
+
acts_as_cached(version: 1, expires_in: 1.week)
|
36
44
|
end
|
37
45
|
```
|
38
46
|
|
@@ -41,14 +49,14 @@ Then it will fetch cached object in this situations:
|
|
41
49
|
```ruby
|
42
50
|
User.find(1)
|
43
51
|
user.articles.find(1)
|
44
|
-
User.where(:
|
52
|
+
User.where(status: 1).find(1)
|
45
53
|
article.user
|
46
54
|
```
|
47
55
|
|
48
56
|
Cache key:
|
49
57
|
|
50
58
|
```ruby
|
51
|
-
user = User.find
|
59
|
+
user = User.find(1)
|
52
60
|
user.second_level_cache_key # We will get the key looks like "slc/user/1/0"
|
53
61
|
```
|
54
62
|
|
@@ -67,7 +75,7 @@ Disable SecondLevelCache:
|
|
67
75
|
|
68
76
|
```ruby
|
69
77
|
User.without_second_level_cache do
|
70
|
-
user = User.find
|
78
|
+
user = User.find(1)
|
71
79
|
# ...
|
72
80
|
end
|
73
81
|
```
|
@@ -111,7 +119,7 @@ DatabaseCleaner.strategy = :truncation
|
|
111
119
|
|
112
120
|
In production env, we recommend to use [Dalli](https://github.com/mperham/dalli) as Rails cache store.
|
113
121
|
```ruby
|
114
|
-
config.cache_store = [:dalli_store, APP_CONFIG["memcached_host"], {:
|
122
|
+
config.cache_store = [:dalli_store, APP_CONFIG["memcached_host"], { namespace: "ns", compress: true }]
|
115
123
|
```
|
116
124
|
|
117
125
|
## Tips:
|
@@ -126,7 +134,7 @@ SecondLevelCache.configure.cache_key_prefix = "slc1"
|
|
126
134
|
|
127
135
|
```ruby
|
128
136
|
class User < ActiveRecord::Base
|
129
|
-
acts_as_cached(:
|
137
|
+
acts_as_cached(version: 2, expires_in: 1.week)
|
130
138
|
end
|
131
139
|
```
|
132
140
|
|
@@ -141,13 +149,6 @@ post = Post.fetch_by_uniq_keys(user_id: 2, slug: "foo")
|
|
141
149
|
user = User.fetch_by_uniq_keys!(nick_name: "hooopo") # this will raise `ActiveRecord::RecordNotFound` Exception when nick name not exists.
|
142
150
|
```
|
143
151
|
|
144
|
-
* multi_read_from_cache
|
145
|
-
|
146
|
-
```ruby
|
147
|
-
# this will use Rails.cache.multi_read method to fetch record, if miss, then use SQL in query.
|
148
|
-
blogs = Blog.multi_read_from_cache([1,2,3])
|
149
|
-
```
|
150
|
-
|
151
152
|
* You can use Rails's [Eager Loading](http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations) feature as normal. Even better, second_level_cache will transform the `IN` query into a Rails.cache.multi_read operation. For example:
|
152
153
|
|
153
154
|
```ruby
|
data/Rakefile
CHANGED
@@ -1,24 +1,20 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
1
|
module SecondLevelCache
|
3
2
|
module ActiveRecord
|
4
3
|
module Base
|
5
|
-
|
4
|
+
def self.prepended(base)
|
5
|
+
base.after_commit :expire_second_level_cache, on: :destroy
|
6
|
+
base.after_commit :update_second_level_cache, on: :update
|
7
|
+
base.after_commit :write_second_level_cache, on: :create
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
-
after_commit :update_second_level_cache, :on => :update
|
10
|
-
after_commit :write_second_level_cache, :on => :create
|
11
|
-
|
12
|
-
class << self
|
13
|
-
alias_method_chain :update_counters, :cache
|
9
|
+
class << base
|
10
|
+
prepend ClassMethods
|
14
11
|
end
|
15
|
-
|
16
12
|
end
|
17
13
|
|
18
14
|
module ClassMethods
|
19
|
-
def
|
20
|
-
|
21
|
-
Array(id).each{|i| expire_second_level_cache(i)}
|
15
|
+
def update_counters(id, counters)
|
16
|
+
super(id, counters).tap do
|
17
|
+
Array(id).each { |i| expire_second_level_cache(i) }
|
22
18
|
end
|
23
19
|
end
|
24
20
|
end
|
@@ -1,25 +1,21 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
1
|
module SecondLevelCache
|
3
2
|
module ActiveRecord
|
4
3
|
module Associations
|
5
4
|
module BelongsToAssociation
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
def find_target
|
6
|
+
return super unless klass.second_level_cache_enabled?
|
7
|
+
cache_record = klass.read_second_level_cache(second_level_cache_key)
|
8
|
+
if cache_record
|
9
|
+
return cache_record.tap { |record| set_inverse_instance(record) }
|
10
10
|
end
|
11
|
-
end
|
12
11
|
|
13
|
-
|
14
|
-
return
|
15
|
-
cache_record = klass.read_second_level_cache(second_level_cache_key)
|
16
|
-
return cache_record.tap{|record| set_inverse_instance(record)} if cache_record
|
17
|
-
record = find_target_without_second_level_cache
|
12
|
+
record = super
|
13
|
+
return nil unless record
|
18
14
|
|
19
15
|
record.tap do |r|
|
20
16
|
set_inverse_instance(r)
|
21
17
|
r.write_second_level_cache
|
22
|
-
end
|
18
|
+
end
|
23
19
|
end
|
24
20
|
|
25
21
|
private
|
@@ -1,20 +1,16 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
1
|
module SecondLevelCache
|
3
2
|
module ActiveRecord
|
4
3
|
module Core
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
class << self
|
9
|
-
alias_method_chain :find, :cache
|
4
|
+
def self.prepended(base)
|
5
|
+
class << base
|
6
|
+
prepend ClassMethods
|
10
7
|
end
|
11
|
-
|
12
8
|
end
|
13
9
|
|
14
10
|
module ClassMethods
|
15
|
-
def
|
16
|
-
return all.find(ids.first) if ids.size == 1 && ids.first.is_a?(
|
17
|
-
|
11
|
+
def find(*ids)
|
12
|
+
return all.find(ids.first) if ids.size == 1 && ids.first.is_a?(Fixnum)
|
13
|
+
super(*ids)
|
18
14
|
end
|
19
15
|
end
|
20
16
|
end
|
@@ -1,39 +1,51 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
1
|
module SecondLevelCache
|
3
2
|
module ActiveRecord
|
4
3
|
module FetchByUniqKey
|
5
4
|
def fetch_by_uniq_keys(where_values)
|
6
5
|
cache_key = cache_uniq_key(where_values)
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
obj_id = SecondLevelCache.cache_store.read(cache_key)
|
7
|
+
if obj_id
|
8
|
+
begin
|
9
|
+
return find(obj_id)
|
10
|
+
rescue
|
11
|
+
return nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
record = where(where_values).first
|
16
|
+
return nil unless record
|
17
|
+
|
18
|
+
record.tap do |r|
|
19
|
+
SecondLevelCache.cache_store.write(cache_key, r.id)
|
12
20
|
end
|
13
21
|
end
|
14
|
-
|
22
|
+
|
15
23
|
def fetch_by_uniq_keys!(where_values)
|
16
|
-
fetch_by_uniq_keys(where_values) ||
|
24
|
+
fetch_by_uniq_keys(where_values) || fail(::ActiveRecord::RecordNotFound)
|
17
25
|
end
|
18
|
-
|
26
|
+
|
19
27
|
def fetch_by_uniq_key(value, uniq_key_name)
|
20
|
-
# puts "[Deprecated] will remove in the future,
|
28
|
+
# puts "[Deprecated] will remove in the future,
|
29
|
+
# use fetch_by_uniq_keys method instead."
|
21
30
|
fetch_by_uniq_keys(uniq_key_name => value)
|
22
31
|
end
|
23
32
|
|
24
33
|
def fetch_by_uniq_key!(value, uniq_key_name)
|
25
|
-
# puts "[Deprecated] will remove in the future,
|
26
|
-
|
34
|
+
# puts "[Deprecated] will remove in the future,
|
35
|
+
# use fetch_by_uniq_keys! method instead."
|
36
|
+
fetch_by_uniq_key(value, uniq_key_name) || fail(::ActiveRecord::RecordNotFound)
|
27
37
|
end
|
28
38
|
|
29
39
|
private
|
30
|
-
|
40
|
+
|
31
41
|
def cache_uniq_key(where_values)
|
32
|
-
|
42
|
+
keys = where_values.collect do |k, v|
|
33
43
|
v = Digest::MD5.hexdigest(v) if v && v.size >= 32
|
34
|
-
[k,v].join(
|
35
|
-
|
36
|
-
|
44
|
+
[k, v].join('_')
|
45
|
+
end
|
46
|
+
|
47
|
+
ext_key = keys.join(',')
|
48
|
+
"uniq_key_#{name}_#{ext_key}"
|
37
49
|
end
|
38
50
|
end
|
39
51
|
end
|
@@ -1,18 +1,12 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
1
|
module SecondLevelCache
|
3
2
|
module ActiveRecord
|
4
3
|
module FinderMethods
|
5
|
-
|
6
|
-
|
7
|
-
included do
|
8
|
-
alias_method_chain :find_one, :second_level_cache
|
9
|
-
alias_method_chain :find_some, :second_level_cache
|
10
|
-
end
|
11
|
-
|
4
|
+
# TODO: find_some
|
5
|
+
# https://github.com/rails/rails/blob/master/activerecord/lib/active_record/relation/finder_methods.rb#L289-L309
|
12
6
|
#
|
13
7
|
# Cacheable:
|
14
8
|
#
|
15
|
-
# current_user.articles.where(:
|
9
|
+
# current_user.articles.where(status: 1).visiable.find(params[:id])
|
16
10
|
#
|
17
11
|
# Uncacheable:
|
18
12
|
#
|
@@ -20,60 +14,41 @@ module SecondLevelCache
|
|
20
14
|
# Article.where("user_id > 1").find(params[:id])
|
21
15
|
# Article.where("articles.user_id = 1").find(prams[:id])
|
22
16
|
# Article.where("user_id = 1 AND ...").find(params[:id])
|
23
|
-
def
|
24
|
-
return
|
25
|
-
return
|
17
|
+
def find_one(id)
|
18
|
+
return super(id) unless second_level_cache_enabled?
|
19
|
+
return super(id) unless select_all_column?
|
26
20
|
|
27
|
-
id = id.id if ActiveRecord::Base
|
21
|
+
id = id.id if ActiveRecord::Base == id
|
28
22
|
|
29
23
|
if cachable?
|
30
24
|
record = @klass.read_second_level_cache(id)
|
31
25
|
if record
|
32
|
-
|
26
|
+
if where_values_hash.blank? || where_values_match_cache?(record)
|
27
|
+
return record
|
28
|
+
end
|
33
29
|
end
|
34
30
|
end
|
35
31
|
|
36
|
-
record =
|
32
|
+
record = super(id)
|
37
33
|
record.write_second_level_cache
|
38
34
|
record
|
39
35
|
end
|
40
36
|
|
41
|
-
|
42
|
-
return find_some_without_second_level_cache(ids) unless second_level_cache_enabled?
|
43
|
-
return find_some_without_second_level_cache(ids) unless select_all_column?
|
44
|
-
|
45
|
-
if cachable?
|
46
|
-
result = multi_read_from_cache(ids)
|
47
|
-
else
|
48
|
-
result = where(:id => ids).all
|
49
|
-
end
|
37
|
+
private
|
50
38
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
expected_size = ids.size - offset_value
|
61
|
-
end
|
62
|
-
|
63
|
-
if result.size == expected_size
|
64
|
-
result
|
65
|
-
else
|
66
|
-
raise_record_not_found_exception!(ids, result.size, expected_size)
|
67
|
-
end
|
39
|
+
def cachable?
|
40
|
+
limit_one? &&
|
41
|
+
order_values.blank? &&
|
42
|
+
includes_values.blank? &&
|
43
|
+
preload_values.blank? &&
|
44
|
+
readonly_value.nil? &&
|
45
|
+
joins_values.blank? &&
|
46
|
+
!@klass.locking_enabled? &&
|
47
|
+
where_clause_match_equality?
|
68
48
|
end
|
69
49
|
|
70
|
-
|
71
|
-
|
72
|
-
def cachable?
|
73
|
-
limit_one? && order_values.blank? &&
|
74
|
-
includes_values.blank? && preload_values.blank? &&
|
75
|
-
readonly_value.nil? && joins_values.blank? && !@klass.locking_enabled? &&
|
76
|
-
where_values.all? { |where_value| where_value.is_a?(::Arel::Nodes::Equality) }
|
50
|
+
def where_clause_match_equality?
|
51
|
+
where_values_hash.all?
|
77
52
|
end
|
78
53
|
|
79
54
|
def where_values_match_cache?(record)
|
@@ -1,35 +1,34 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
1
|
module SecondLevelCache
|
3
2
|
module ActiveRecord
|
4
3
|
module Associations
|
5
4
|
module HasOneAssociation
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def find_target_with_second_level_cache
|
14
|
-
return find_target_without_second_level_cache unless klass.second_level_cache_enabled?
|
5
|
+
def find_target
|
6
|
+
return super unless klass.second_level_cache_enabled?
|
7
|
+
return super if reflection.options[:through] || reflection.scope
|
8
|
+
# TODO: implement cache with has_one through, scope
|
15
9
|
|
16
|
-
|
17
|
-
# TODO: implement cache with has_one through
|
10
|
+
owner_primary_key = owner[reflection.active_record_primary_key]
|
18
11
|
if reflection.options[:as]
|
19
|
-
|
20
|
-
|
21
|
-
|
12
|
+
keys = {
|
13
|
+
reflection.foreign_key => owner_primary_key,
|
14
|
+
reflection.type => owner.class.base_class.name
|
15
|
+
}
|
16
|
+
cache_record = klass.fetch_by_uniq_keys(keys)
|
22
17
|
else
|
23
|
-
cache_record = klass.fetch_by_uniq_key(
|
18
|
+
cache_record = klass.fetch_by_uniq_key(owner_primary_key, reflection.foreign_key)
|
24
19
|
end
|
25
|
-
return cache_record.tap{|record| set_inverse_instance(record)} if cache_record
|
26
20
|
|
27
|
-
|
21
|
+
if cache_record
|
22
|
+
return cache_record.tap { |record| set_inverse_instance(record) }
|
23
|
+
end
|
24
|
+
|
25
|
+
record = super
|
26
|
+
return nil unless record
|
28
27
|
|
29
28
|
record.tap do |r|
|
30
29
|
set_inverse_instance(r)
|
31
30
|
r.write_second_level_cache
|
32
|
-
end
|
31
|
+
end
|
33
32
|
end
|
34
33
|
end
|
35
34
|
end
|
@@ -1,28 +1,17 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
1
|
module SecondLevelCache
|
3
2
|
module ActiveRecord
|
4
3
|
module Persistence
|
5
|
-
|
6
|
-
|
7
|
-
included do
|
8
|
-
class_eval do
|
9
|
-
alias_method_chain :reload, :second_level_cache
|
10
|
-
alias_method_chain :touch, :second_level_cache
|
11
|
-
alias_method_chain :update_column, :second_level_cache
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
def update_column_with_second_level_cache(name, value)
|
16
|
-
update_column_without_second_level_cache(name, value).tap{update_second_level_cache}
|
4
|
+
def update_column(name, value)
|
5
|
+
super(name, value).tap { update_second_level_cache }
|
17
6
|
end
|
18
7
|
|
19
|
-
def
|
8
|
+
def reload(options = nil)
|
20
9
|
expire_second_level_cache
|
21
|
-
|
10
|
+
super(options)
|
22
11
|
end
|
23
12
|
|
24
|
-
def
|
25
|
-
|
13
|
+
def touch(*names)
|
14
|
+
super(*names).tap { update_second_level_cache }
|
26
15
|
end
|
27
16
|
end
|
28
17
|
end
|
@@ -1,34 +1,33 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
1
|
module SecondLevelCache
|
3
2
|
module ActiveRecord
|
4
3
|
module Associations
|
5
4
|
class Preloader
|
6
5
|
module BelongsTo
|
7
|
-
|
6
|
+
def records_for(ids)
|
7
|
+
return super(ids) unless klass.second_level_cache_enabled?
|
8
8
|
|
9
|
-
|
10
|
-
alias_method_chain :records_for, :second_level_cache
|
11
|
-
end
|
12
|
-
|
13
|
-
def records_for_with_second_level_cache(ids)
|
14
|
-
return records_for_without_second_level_cache(ids) unless klass.second_level_cache_enabled?
|
15
|
-
|
16
|
-
map_cache_keys = ids.map{|id| klass.second_level_cache_key(id)}
|
9
|
+
map_cache_keys = ids.map { |id| klass.second_level_cache_key(id) }
|
17
10
|
records_from_cache = ::SecondLevelCache.cache_store.read_multi(*map_cache_keys)
|
18
11
|
# NOTICE
|
19
12
|
# Rails.cache.read_multi return hash that has keys only hitted.
|
20
13
|
# eg. Rails.cache.read_multi(1,2,3) => {2 => hit_value, 3 => hit_value}
|
21
|
-
hitted_ids = records_from_cache.map{|key, _| key.split(
|
22
|
-
missed_ids = ids.map
|
14
|
+
hitted_ids = records_from_cache.map { |key, _| key.split('/')[2].to_i }
|
15
|
+
missed_ids = ids.map(&:to_i) - hitted_ids
|
16
|
+
|
17
|
+
::SecondLevelCache.logger.info "missed ids -> #{missed_ids.inspect} | hitted ids -> #{hitted_ids.inspect}"
|
23
18
|
|
24
|
-
|
19
|
+
record_marshals = RecordMarshal.load_multi(records_from_cache.values)
|
25
20
|
|
26
21
|
if missed_ids.empty?
|
27
|
-
|
28
|
-
else
|
29
|
-
records_from_db = records_for_without_second_level_cache(missed_ids)
|
30
|
-
records_from_db.map{|record| write_cache(record); record} + RecordMarshal.load_multi(records_from_cache.values)
|
22
|
+
return record_marshals
|
31
23
|
end
|
24
|
+
|
25
|
+
records_from_db = super(missed_ids)
|
26
|
+
records_from_db.map do |r|
|
27
|
+
write_cache(r)
|
28
|
+
end
|
29
|
+
|
30
|
+
records_from_db + record_marshals
|
32
31
|
end
|
33
32
|
|
34
33
|
private
|
@@ -1,13 +1,16 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
module SecondLevelCache
|
2
|
+
module ActiveRecord
|
3
|
+
class Railtie < Rails::Railtie
|
4
|
+
initializer 'second_level_cache.active_record.initialization' do
|
5
|
+
::ActiveRecord::Base.send(:include, SecondLevelCache::Mixin)
|
6
|
+
::ActiveRecord::Base.send(:prepend, SecondLevelCache::ActiveRecord::Base)
|
7
|
+
::ActiveRecord::Base.send(:extend, SecondLevelCache::ActiveRecord::FetchByUniqKey)
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
::ActiveRecord::Base.send(:prepend, SecondLevelCache::ActiveRecord::Persistence)
|
10
|
+
::ActiveRecord::Associations::BelongsToAssociation.send(:prepend, SecondLevelCache::ActiveRecord::Associations::BelongsToAssociation)
|
11
|
+
::ActiveRecord::Associations::HasOneAssociation.send(:prepend, SecondLevelCache::ActiveRecord::Associations::HasOneAssociation)
|
12
|
+
::ActiveRecord::Associations::Preloader::BelongsTo.send(:prepend, SecondLevelCache::ActiveRecord::Associations::Preloader::BelongsTo)
|
13
|
+
end
|
14
|
+
end
|
12
15
|
end
|
13
16
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
1
|
require 'second_level_cache/active_record/base'
|
3
2
|
require 'second_level_cache/active_record/core'
|
4
3
|
require 'second_level_cache/active_record/fetch_by_uniq_key'
|
@@ -7,18 +6,16 @@ require 'second_level_cache/active_record/persistence'
|
|
7
6
|
require 'second_level_cache/active_record/belongs_to_association'
|
8
7
|
require 'second_level_cache/active_record/has_one_association'
|
9
8
|
require 'second_level_cache/active_record/preloader'
|
10
|
-
require 'second_level_cache/active_record/multi_read_from_cache'
|
11
9
|
|
12
10
|
if defined? Rails
|
13
11
|
require 'second_level_cache/active_record/railtie'
|
14
12
|
else
|
15
13
|
ActiveRecord::Base.send(:include, SecondLevelCache::Mixin)
|
16
|
-
ActiveRecord::Base.send(:
|
14
|
+
ActiveRecord::Base.send(:prepend, SecondLevelCache::ActiveRecord::Base)
|
17
15
|
ActiveRecord::Base.send(:extend, SecondLevelCache::ActiveRecord::FetchByUniqKey)
|
18
|
-
ActiveRecord::Base.send(:extend, SecondLevelCache::ActiveRecord::MultiReadFromCache)
|
19
16
|
|
20
|
-
ActiveRecord::Base.send(:
|
21
|
-
ActiveRecord::Associations::BelongsToAssociation.send(:
|
22
|
-
ActiveRecord::Associations::HasOneAssociation.send(:
|
23
|
-
ActiveRecord::Associations::Preloader::BelongsTo.send(:
|
17
|
+
ActiveRecord::Base.send(:prepend, SecondLevelCache::ActiveRecord::Persistence)
|
18
|
+
ActiveRecord::Associations::BelongsToAssociation.send(:prepend, SecondLevelCache::ActiveRecord::Associations::BelongsToAssociation)
|
19
|
+
ActiveRecord::Associations::HasOneAssociation.send(:prepend, SecondLevelCache::ActiveRecord::Associations::HasOneAssociation)
|
20
|
+
ActiveRecord::Associations::Preloader::BelongsTo.send(:prepend, SecondLevelCache::ActiveRecord::Associations::Preloader::BelongsTo)
|
24
21
|
end
|
@@ -1,22 +1,21 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
1
|
module SecondLevelCache
|
3
|
-
|
4
|
-
|
2
|
+
class Config
|
3
|
+
class << self
|
4
|
+
attr_accessor :cache_store, :logger, :cache_key_prefix
|
5
5
|
|
6
|
-
|
6
|
+
def cache_store
|
7
|
+
@cache_store ||= Rails.cache if defined?(Rails)
|
8
|
+
@cache_store
|
9
|
+
end
|
7
10
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
def logger
|
14
|
-
@logger ||= Rails.logger if defined?(Rails)
|
15
|
-
@logger ||= Logger.new(STDOUT)
|
16
|
-
end
|
11
|
+
def logger
|
12
|
+
@logger ||= Rails.logger if defined?(Rails)
|
13
|
+
@logger ||= Logger.new(STDOUT)
|
14
|
+
end
|
17
15
|
|
18
|
-
|
19
|
-
|
16
|
+
def cache_key_prefix
|
17
|
+
@cache_key_prefix ||= 'slc'
|
18
|
+
end
|
20
19
|
end
|
21
20
|
end
|
22
21
|
end
|