scoped_cache_keys 0.1.1 → 0.3.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 599264adc7feb1e042fde17a4473126615907cfd03e27172d9355f9c5dfc6308
4
+ data.tar.gz: bd9335f025963374103c7fd8a0a897606e977b02568ba1a5816cc55a7f8f9afd
5
+ SHA512:
6
+ metadata.gz: 9740614f52aeb1c14a7462ac11c1c4a496146402a7973f76991651bd3480ebf2e95754af17962ebecb2f1dab544fe56c7555f86b0d578be7032f374acbe26bf2
7
+ data.tar.gz: 9d2dc9a88572ef4991280a50bd9c764041d96d9996f8bc548b07cde2ecc614d7e5a619979099cc92c33af497b79816cfc5c8691fa0f56bd681261bd49bc058fc
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ .ruby-version
data/Gemfile CHANGED
@@ -1,4 +1,5 @@
1
- source :rubygems
1
+ source "https://rubygems.org"
2
+
2
3
  gemspec
3
4
 
4
5
  gem 'rake'
data/Gemfile.lock CHANGED
@@ -1,39 +1,41 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- scoped_cache_keys (0.1.1)
4
+ scoped_cache_keys (0.3.0)
5
5
 
6
6
  GEM
7
- remote: http://rubygems.org/
7
+ remote: https://rubygems.org/
8
8
  specs:
9
- activemodel (3.2.3)
10
- activesupport (= 3.2.3)
11
- builder (~> 3.0.0)
12
- activerecord (3.2.3)
13
- activemodel (= 3.2.3)
14
- activesupport (= 3.2.3)
15
- arel (~> 3.0.2)
16
- tzinfo (~> 0.3.29)
17
- activesupport (3.2.3)
18
- i18n (~> 0.6)
19
- multi_json (~> 1.0)
20
- arel (3.0.2)
21
- builder (3.0.0)
22
- diff-lcs (1.1.3)
23
- i18n (0.6.0)
24
- multi_json (1.3.4)
25
- rake (0.9.2)
26
- rspec (2.6.0)
27
- rspec-core (~> 2.6.0)
28
- rspec-expectations (~> 2.6.0)
29
- rspec-mocks (~> 2.6.0)
30
- rspec-core (2.6.4)
31
- rspec-expectations (2.6.0)
32
- diff-lcs (~> 1.1.2)
33
- rspec-mocks (2.6.0)
34
- sqlite3 (1.3.6)
35
- timecop (0.3.5)
36
- tzinfo (0.3.33)
9
+ activemodel (7.0.4)
10
+ activesupport (= 7.0.4)
11
+ activerecord (7.0.4)
12
+ activemodel (= 7.0.4)
13
+ activesupport (= 7.0.4)
14
+ activesupport (7.0.4)
15
+ concurrent-ruby (~> 1.0, >= 1.0.2)
16
+ i18n (>= 1.6, < 2)
17
+ minitest (>= 5.1)
18
+ tzinfo (~> 2.0)
19
+ concurrent-ruby (1.1.10)
20
+ diff-lcs (1.5.0)
21
+ i18n (1.12.0)
22
+ concurrent-ruby (~> 1.0)
23
+ mini_portile2 (2.8.0)
24
+ minitest (5.16.3)
25
+ rake (13.0.6)
26
+ rspec (2.99.0)
27
+ rspec-core (~> 2.99.0)
28
+ rspec-expectations (~> 2.99.0)
29
+ rspec-mocks (~> 2.99.0)
30
+ rspec-core (2.99.2)
31
+ rspec-expectations (2.99.2)
32
+ diff-lcs (>= 1.1.3, < 2.0)
33
+ rspec-mocks (2.99.4)
34
+ sqlite3 (1.5.3)
35
+ mini_portile2 (~> 2.8.0)
36
+ timecop (0.9.5)
37
+ tzinfo (2.0.5)
38
+ concurrent-ruby (~> 1.0)
37
39
 
38
40
  PLATFORMS
39
41
  ruby
@@ -45,3 +47,6 @@ DEPENDENCIES
45
47
  scoped_cache_keys!
46
48
  sqlite3
47
49
  timecop
50
+
51
+ BUNDLED WITH
52
+ 2.3.12
data/Readme.md CHANGED
@@ -1,25 +1,104 @@
1
- Add scoped_cache_key / expire_scoped_cache_key to your models for caching/sweeping of model-related caches.
1
+ scoped_cache_keys
2
+ =================
3
+
4
+ Add `scoped_cache_key` / `expire_scoped_cache_key` to your models for caching/sweeping of model-related caches.
5
+
6
+ Overview
7
+ --------
8
+
9
+ `scoped_cache_keys` enables you to "scope" multiple cache entries together, such that they can be expired
10
+ together in a single operation.
11
+
12
+ This saves the trouble of having to delete several individual cache entries, and improves the consistency
13
+ of your cache entries by having them all expire together.
14
+
15
+ Model-related caches in a Rails application often consist of multiple cache entries, which should be
16
+ consistent with each other.
17
+
18
+ For instance, you might have a cache entry which is a key->value mapping for a model, but another
19
+ cache entry which is a value->key mapping.
2
20
 
3
21
  Install
4
- =======
5
- sudo gem install scoped_cache_keys
6
- Or
22
+ -------
7
23
 
8
- rails plugin install git://github.com/grosser/scoped_cache_keys.git
24
+ ```bash
25
+ gem "scoped_cache_keys"
26
+ ```
9
27
 
10
28
  Usage
11
- =====
29
+ -----
30
+
31
+ To use `scoped_cached_keys`, use `include ScopedCacheKeys` in your model declaration:
32
+
33
+ ```ruby
34
+ class User < ActiveRecord::Base
35
+ include ScopedCacheKeys
36
+ ...
37
+ end
38
+ ```
39
+
40
+ ### scoped_cache_key ###
41
+
42
+ The `scoped_cache_key` method returns a key that will change whenever `expire_scoped_cache_key` is called.
43
+ The cache key will be scoped to the model object that `scoped_cache_key` is invoked on, along with
44
+ whatever scope is passed:
45
+
46
+ ```ruby
47
+ account.scoped_cache_key(:orders)
48
+ ```
49
+
50
+ Options: Any caching options that are passed to `Rails.cache` methods may be passed to `scoped_cache_key`.
51
+ For example:
52
+
53
+ ```ruby
54
+ account.scoped_cache_key(:orders, expires_in: 10.minutes)
55
+ ```
56
+
57
+ The key that is returned can be treated as a "base key," that is, concatenated with other strings to form
58
+ other cache keys. All such cache keys will become unreachable, and thus "expired," when
59
+ `expire_scoped_cache_key` is called.
60
+
61
+ ### expire_scoped_cache_key ###
62
+
63
+ The `expire_scoped_cache_key` method will expire a scoped cache key obtained with `scoped_cache_key`.
64
+ Example:
65
+
66
+ ```ruby
67
+ account.expire_scoped_cache_key(:orders)
68
+ ```
69
+
70
+ Options: The optional `delay` parameter specifies an amount of time to delay before actually expiring
71
+ the scoped cache key. Example:
72
+
73
+ ```ruby
74
+ account.expire_scoped_cache_key(:orders, delay: 5.seconds)
75
+ ```
76
+
77
+ The `delay` parameter can be useful for contending with database replication lag. When many concurrent
78
+ processes access the scoped cache entries, one or more may immediately try to rebuild the cache
79
+ the instant that `expire_scoped_cache_key` completes. This could happen so quickly that the database
80
+ replicas may not be caught up with the model changes that were just committed. Alternately, one
81
+ could force the models to be queried from the primary database to avoid such race conditions.
82
+
83
+ The expiration delay may also be set at a global level:
84
+
85
+ ```ruby
86
+ ScopedCacheKeys.expire_scoped_cache_key_delay = 10.seconds
87
+ ```
12
88
 
13
- Gives you a key that will change whenever expire_scoped_cache_key is called.
89
+ ### Example ###
14
90
 
91
+ ```
15
92
  <% cache user.scoped_cache_key :products do %>
16
93
  ... user.products.each ...
17
94
  <% end %>
18
95
 
19
- <% cache "something-else-" + user.scoped_cache_key :products %>
96
+ <% cache "something-else-" + user.scoped_cache_key(:products) do %>
20
97
  ... will also be expired ...
21
98
  <% end %>
99
+ ```
22
100
 
101
+ ```ruby
23
102
  # app/sweepers/product_sweeper.rb
24
103
  class ProductSweeper < ActionController::Caching::Sweeper
25
104
  observe Product
@@ -28,10 +107,10 @@ Gives you a key that will change whenever expire_scoped_cache_key is called.
28
107
  record.user.expire_scoped_cache_key :products
29
108
  end
30
109
  end
110
+ ```
31
111
 
32
112
  Author
33
- ======
113
+ ------
34
114
  [Zendesk](http://zendesk.com)<br/>
35
115
  michael@grosser.it<br/>
36
- License: MIT<br/>
37
- [![Build Status](https://secure.travis-ci.org/grosser/scoped_cache_keys.png)](http://travis-ci.org/grosser/scoped_cache_keys)
116
+ License: MIT
@@ -1,3 +1,3 @@
1
1
  module ScopedCacheKeys
2
- VERSION = '0.1.1'
2
+ VERSION = '0.3.0'
3
3
  end
@@ -1,13 +1,26 @@
1
1
  require 'scoped_cache_keys/version'
2
2
 
3
3
  module ScopedCacheKeys
4
- def scoped_cache_key(scope)
5
- base_key = Rails.cache.fetch(build_scoped_cache_key([scope])){ Time.now.to_f }
4
+ class << self
5
+ # If set, expire_scoped_cache_key will delay expiration by this many seconds
6
+ # globally.
7
+ attr_accessor :expire_scoped_cache_key_delay
8
+ end
9
+
10
+ def scoped_cache_key(scope, options = nil)
11
+ base_key = Rails.cache.fetch(build_scoped_cache_key([scope]), options) { Time.now.to_f }
6
12
  build_scoped_cache_key [scope, base_key]
7
13
  end
8
14
 
9
- def expire_scoped_cache_key(scope)
10
- Rails.cache.delete(build_scoped_cache_key(scope))
15
+ def expire_scoped_cache_key(scope, delay: nil)
16
+ delay ||= ScopedCacheKeys.expire_scoped_cache_key_delay
17
+ key = build_scoped_cache_key(scope)
18
+ if delay
19
+ entry = Rails.cache.read(key)
20
+ Rails.cache.write(key, entry, expires_in: delay) if entry
21
+ else
22
+ Rails.cache.delete(key)
23
+ end
11
24
  end
12
25
 
13
26
  private
@@ -45,6 +45,12 @@ describe ScopedCacheKeys do
45
45
  user.updated_at = 1.week.ago
46
46
  }.to_not change{ user.scoped_cache_key(:foo) }
47
47
  end
48
+
49
+ it "accepts cache options such as expired_in" do
50
+ key = user.scoped_cache_key(:foo, expires_in: 10.seconds)
51
+ Timecop.travel(11.seconds.from_now)
52
+ user.scoped_cache_key(:foo).should_not == key
53
+ end
48
54
  end
49
55
 
50
56
  describe "#expire_scoped_cache_key" do
@@ -59,5 +65,25 @@ describe ScopedCacheKeys do
59
65
  user.expire_scoped_cache_key :bar
60
66
  }.to_not change{ user.scoped_cache_key(:foo) }
61
67
  end
68
+
69
+ it "expires a specific scope after a specified delay" do
70
+ key = user.scoped_cache_key :foo
71
+ user.expire_scoped_cache_key :foo, delay: 5.seconds
72
+ Timecop.travel(4.seconds.from_now)
73
+ user.scoped_cache_key(:foo).should == key
74
+ Timecop.travel(2.seconds.from_now)
75
+ user.scoped_cache_key(:foo).should_not == key
76
+ end
77
+
78
+ it "expires a specific scope after a specified global delay" do
79
+ ScopedCacheKeys.expire_scoped_cache_key_delay = 10.seconds
80
+ key = user.scoped_cache_key :foo
81
+ user.expire_scoped_cache_key :foo
82
+ Timecop.travel(9.seconds.from_now)
83
+ user.scoped_cache_key(:foo).should == key
84
+ Timecop.travel(2.seconds.from_now)
85
+ user.scoped_cache_key(:foo).should_not == key
86
+ ScopedCacheKeys.expire_scoped_cache_key_delay = nil
87
+ end
62
88
  end
63
89
  end
metadata CHANGED
@@ -1,33 +1,22 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: scoped_cache_keys
3
- version: !ruby/object:Gem::Version
4
- hash: 25
5
- prerelease:
6
- segments:
7
- - 0
8
- - 1
9
- - 1
10
- version: 0.1.1
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
11
5
  platform: ruby
12
- authors:
6
+ authors:
13
7
  - Michael Grosser
14
8
  autorequire:
15
9
  bindir: bin
16
10
  cert_chain: []
17
-
18
- date: 2012-05-04 00:00:00 Z
11
+ date: 2022-12-02 00:00:00.000000000 Z
19
12
  dependencies: []
20
-
21
13
  description:
22
14
  email: michael@grosser.it
23
15
  executables: []
24
-
25
16
  extensions: []
26
-
27
17
  extra_rdoc_files: []
28
-
29
- files:
30
- - .travis.yml
18
+ files:
19
+ - ".gitignore"
31
20
  - Gemfile
32
21
  - Gemfile.lock
33
22
  - Rakefile
@@ -38,37 +27,27 @@ files:
38
27
  - spec/scoped_cache_keys_spec.rb
39
28
  - spec/spec_helper.rb
40
29
  homepage: http://github.com/grosser/scoped_cache_keys
41
- licenses:
30
+ licenses:
42
31
  - MIT
32
+ metadata: {}
43
33
  post_install_message:
44
34
  rdoc_options: []
45
-
46
- require_paths:
35
+ require_paths:
47
36
  - lib
48
- required_ruby_version: !ruby/object:Gem::Requirement
49
- none: false
50
- requirements:
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ requirements:
51
39
  - - ">="
52
- - !ruby/object:Gem::Version
53
- hash: 3
54
- segments:
55
- - 0
56
- version: "0"
57
- required_rubygems_version: !ruby/object:Gem::Requirement
58
- none: false
59
- requirements:
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ required_rubygems_version: !ruby/object:Gem::Requirement
43
+ requirements:
60
44
  - - ">="
61
- - !ruby/object:Gem::Version
62
- hash: 3
63
- segments:
64
- - 0
65
- version: "0"
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
66
47
  requirements: []
67
-
68
- rubyforge_project:
69
- rubygems_version: 1.8.24
48
+ rubygems_version: 3.1.6
70
49
  signing_key:
71
- specification_version: 3
72
- summary: Add scoped_cache_key / expire_scoped_cache_key to your models for caching/sweeping of model-related caches + touch_if_necessary
50
+ specification_version: 4
51
+ summary: Add scoped_cache_key / expire_scoped_cache_key to your models for caching/sweeping
52
+ of model-related caches + touch_if_necessary
73
53
  test_files: []
74
-
data/.travis.yml DELETED
@@ -1,5 +0,0 @@
1
- script: "bundle exec rake"
2
- rvm:
3
- - ree
4
- - 1.9.2
5
- - 1.9.3