identity_cache 1.5.6 → 1.6.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ffba8f1b3669ad74b16896e59c3b4f669d5802f96ce2fad7ead33ac06b16880c
4
- data.tar.gz: 74edc98197bd0671dd39ac6446553b23998c1c3a67a122ba916e2542ea7bfcdb
3
+ metadata.gz: 1cb45582de9a181e4b32595a183630023ba9af3a84ed5123308eada240420ab8
4
+ data.tar.gz: 46ce8b2795adbd03ca67d69ba9ddd725ac1b7bcbf56ac85344ee220380495ad4
5
5
  SHA512:
6
- metadata.gz: c09f6b0e32127203cde69cff41bae906577781d43222115fe34b8632a886d4bec78f7878928e20128f63cd3c39445a8b447ef7ee224a47e8f9b65982e01be339
7
- data.tar.gz: 7a4bb522ed8674102bcbaf35cb853f2f2816f501e0349c52154214519559f03a5dc876c1ba318296f17c9dece94153e37157cac9afbeaecebb6bbf7a1a4eecbc
6
+ metadata.gz: 5a4053d1a93c89a058593fc998dad0c77ac32aae4d691db3087bd88743bae2aa76193112262e0ac536468c3ddc14ceef5fd34e2d770d7e8d3129d83df65d604d
7
+ data.tar.gz: e397cb05b4d7bc5a3a6304fc4346ac63318c043c44dee032730af30c23a19d42168f0390039d6986aeef33dfda28e99dda831ca23dca8ea217a356d736dccd6e
@@ -19,11 +19,11 @@ jobs:
19
19
  ruby: '3.0'
20
20
  gemfile: "Gemfile.min-supported"
21
21
  - name: 'Latest released & run rubocop'
22
- ruby: '3.2'
22
+ ruby: '3.3'
23
23
  gemfile: "Gemfile.latest-release"
24
24
  rubocop: true
25
25
  - name: 'Rails edge'
26
- ruby: '3.2'
26
+ ruby: '3.3'
27
27
  gemfile: "Gemfile.rails-edge"
28
28
  edge: true
29
29
 
@@ -69,25 +69,26 @@ jobs:
69
69
  run: |
70
70
  sudo apt-get update
71
71
  sudo apt-get -y install libmemcached-dev libmysqlclient-dev libpq-dev libsasl2-dev
72
+
72
73
  - uses: actions/checkout@v2
73
74
  - name: Set up Ruby
74
75
  uses: ruby/setup-ruby@v1
75
76
  with:
76
77
  ruby-version: ${{ matrix.entry.ruby }}
77
- - name: Install bundler and gems
78
- run: |
79
- gem install bundler
80
- bundle install --jobs 4 --retry 3
78
+ bundler-cache: true
79
+
81
80
  - name: Test with mysql
82
81
  env:
83
82
  DB: mysql2
84
83
  run: bundle exec rake test
84
+
85
85
  - name: Test with postgres and memcached_store
86
86
  env:
87
87
  DB: postgresql
88
88
  POSTGRES_PASSWORD: postgres
89
89
  ADAPTER: memcached
90
90
  run: bundle exec rake test
91
+
91
92
  - name: Run rubocop
92
93
  if: matrix.entry.rubocop
93
94
  run: bundle exec rubocop
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.2.2
1
+ 3.3.4
data/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 1.6.1
6
+
7
+ - Fix deprecation warnings on Active Record 7.2. (#575)
8
+
9
+ ## 1.6.0
10
+
11
+ - Introduce `.with_deferred_parent_expiration`, which takes a block and avoids duplicate parent cache expiry. (#569)
12
+
5
13
  ## 1.5.6
6
14
 
7
15
  - Minor performance improvements on association read
data/Gemfile CHANGED
@@ -9,9 +9,9 @@ gem "rubocop-shopify", "~> 2.9.0", require: false
9
9
 
10
10
  gem "mysql2", "~> 0.5.3", platform: :mri
11
11
  gem "pg", ">= 0.18", "< 2.0", platform: :mri
12
- gem "memcached", "~> 1.8.0", platform: :mri
12
+ gem "memcached", github: "Shopify/memcached", branch: "1-0-stable-shopify", platform: :mri
13
13
  gem "memcached_store", "~> 2.3.2", platform: :mri
14
- gem "dalli", "~> 2.7.11"
14
+ gem "dalli", "~> 3.2.3"
15
15
  gem "cityhash", "~> 0.6.0", platform: :mri
16
16
 
17
17
  gem "byebug", platform: :mri
data/Gemfile.lock CHANGED
@@ -1,52 +1,59 @@
1
+ GIT
2
+ remote: https://github.com/Shopify/memcached.git
3
+ revision: 54a89bae698896a00fd2ceeb142dada6285f73ed
4
+ branch: 1-0-stable-shopify
5
+ specs:
6
+ memcached (1.9.0)
7
+
1
8
  PATH
2
9
  remote: .
3
10
  specs:
4
- identity_cache (1.5.6)
11
+ identity_cache (1.6.1)
5
12
  activerecord (>= 7.0)
6
13
  ar_transaction_changes (~> 1.1)
7
14
 
8
15
  GEM
9
16
  remote: https://rubygems.org/
10
17
  specs:
11
- activemodel (7.1.3.2)
12
- activesupport (= 7.1.3.2)
13
- activerecord (7.1.3.2)
14
- activemodel (= 7.1.3.2)
15
- activesupport (= 7.1.3.2)
18
+ activemodel (7.2.0)
19
+ activesupport (= 7.2.0)
20
+ activerecord (7.2.0)
21
+ activemodel (= 7.2.0)
22
+ activesupport (= 7.2.0)
16
23
  timeout (>= 0.4.0)
17
- activesupport (7.1.3.2)
24
+ activesupport (7.2.0)
18
25
  base64
19
26
  bigdecimal
20
- concurrent-ruby (~> 1.0, >= 1.0.2)
27
+ concurrent-ruby (~> 1.0, >= 1.3.1)
21
28
  connection_pool (>= 2.2.5)
22
29
  drb
23
30
  i18n (>= 1.6, < 2)
31
+ logger (>= 1.4.2)
24
32
  minitest (>= 5.1)
25
- mutex_m
26
- tzinfo (~> 2.0)
33
+ securerandom (>= 0.3)
34
+ tzinfo (~> 2.0, >= 2.0.5)
27
35
  ar_transaction_changes (1.1.9)
28
36
  activerecord (>= 5.2.0)
29
37
  ast (2.4.2)
30
38
  base64 (0.2.0)
31
- bigdecimal (3.1.6)
39
+ bigdecimal (3.1.8)
32
40
  byebug (11.1.3)
33
41
  cityhash (0.6.0)
34
- concurrent-ruby (1.2.3)
42
+ concurrent-ruby (1.3.4)
35
43
  connection_pool (2.4.1)
36
- dalli (2.7.11)
44
+ dalli (3.2.3)
37
45
  drb (2.2.1)
38
- i18n (1.14.4)
46
+ i18n (1.14.5)
39
47
  concurrent-ruby (~> 1.0)
40
48
  json (2.7.1)
41
49
  language_server-protocol (3.17.0.3)
42
- memcached (1.8.0)
50
+ logger (1.6.0)
43
51
  memcached_store (2.3.4)
44
52
  activesupport (>= 6)
45
53
  memcached (~> 1.8)
46
- minitest (5.22.2)
54
+ minitest (5.25.1)
47
55
  mocha (2.1.0)
48
56
  ruby2_keywords (>= 0.0.5)
49
- mutex_m (0.2.0)
50
57
  mysql2 (0.5.6)
51
58
  parallel (1.24.0)
52
59
  parser (3.3.0.5)
@@ -57,7 +64,8 @@ GEM
57
64
  rainbow (3.1.1)
58
65
  rake (13.1.0)
59
66
  regexp_parser (2.9.0)
60
- rexml (3.2.6)
67
+ rexml (3.2.8)
68
+ strscan (>= 3.0.9)
61
69
  rubocop (1.61.0)
62
70
  json (~> 2.3)
63
71
  language_server-protocol (>= 3.17.0)
@@ -75,8 +83,10 @@ GEM
75
83
  rubocop (~> 1.33)
76
84
  ruby-progressbar (1.13.0)
77
85
  ruby2_keywords (0.0.5)
86
+ securerandom (0.3.1)
78
87
  spy (1.0.5)
79
88
  stackprof (0.2.26)
89
+ strscan (3.1.0)
80
90
  timeout (0.4.1)
81
91
  tzinfo (2.0.6)
82
92
  concurrent-ruby (~> 1.0)
@@ -84,14 +94,15 @@ GEM
84
94
 
85
95
  PLATFORMS
86
96
  arm64-darwin-22
97
+ arm64-darwin-23
87
98
  x86_64-linux
88
99
 
89
100
  DEPENDENCIES
90
101
  byebug
91
102
  cityhash (~> 0.6.0)
92
- dalli (~> 2.7.11)
103
+ dalli (~> 3.2.3)
93
104
  identity_cache!
94
- memcached (~> 1.8.0)
105
+ memcached!
95
106
  memcached_store (~> 2.3.2)
96
107
  minitest (~> 5.14)
97
108
  mocha (~> 2.0)
data/dev.yml CHANGED
@@ -1,18 +1,10 @@
1
1
  name: identity-cache
2
2
 
3
3
  up:
4
- - homebrew:
5
- - mysql-client@5.7:
6
- or: [mysql@5.7]
7
- conflicts: [mysql-connector-c, mysql, mysql-client]
8
4
  - ruby
9
- - isogun
10
5
  - bundler
11
-
12
- env:
13
- RAILGUN_HOST: identity-cache.railgun
14
- MYSQL_HOST: identity-cache.railgun
15
- MEMCACHED_HOST: identity-cache.railgun
6
+ - memcached
7
+ - mysql
16
8
 
17
9
  commands:
18
10
  test:
@@ -8,6 +8,7 @@ gem "activerecord"
8
8
  gem "activesupport"
9
9
  gem "mysql2", "~> 0.5"
10
10
  gem "pg", "~> 1.1"
11
+ gem "memcached", github: "Shopify/memcached", branch: "1-0-stable-shopify"
11
12
  gem "memcached_store"
12
13
  gem "dalli"
13
14
  gem "cityhash"
@@ -6,7 +6,7 @@ gem "ar_transaction_changes", "~> 1.1.0"
6
6
  gem "activerecord", "~> 7.0.0"
7
7
  gem "mysql2", "~> 0.5"
8
8
  gem "pg", "~> 1.1"
9
- gem "memcached", "~> 1.8.0"
9
+ gem "memcached", github: "Shopify/memcached", branch: "1-0-stable-shopify"
10
10
  gem "memcached_store", "~> 2.3.2"
11
11
  gem "dalli", "~> 2.7.11"
12
12
  gem "cityhash", "~> 0.6.0"
@@ -5,6 +5,7 @@ gem "activerecord", github: "rails/rails", branch: "main"
5
5
  gem "activesupport", github: "rails/rails", branch: "main"
6
6
  gem "mysql2", "~> 0.5"
7
7
  gem "pg", "~> 1.1"
8
+ gem "memcached", github: "Shopify/memcached", branch: "1-0-stable-shopify"
8
9
  gem "memcached_store"
9
10
  gem "dalli"
10
11
  gem "cityhash"
@@ -47,6 +47,10 @@ module IdentityCache
47
47
  add_parents_to_cache_expiry_set(parents_to_expire)
48
48
  parents_to_expire.select! { |parent| parent.class.primary_cache_index_enabled }
49
49
  parents_to_expire.reduce(true) do |all_expired, parent|
50
+ if Thread.current[:idc_deferred_parent_expiration]
51
+ Thread.current[:idc_parent_records_for_cache_expiry] << parent
52
+ next parent
53
+ end
50
54
  parent.expire_primary_index && all_expired
51
55
  end
52
56
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module IdentityCache
4
- VERSION = "1.5.6"
4
+ VERSION = "1.6.1"
5
5
  CACHE_VERSION = 8
6
6
  end
@@ -60,6 +60,8 @@ module IdentityCache
60
60
 
61
61
  class InverseAssociationError < StandardError; end
62
62
 
63
+ class NestedDeferredParentBlockError < StandardError; end
64
+
63
65
  class UnsupportedScopeError < StandardError; end
64
66
 
65
67
  class UnsupportedAssociationError < StandardError; end
@@ -115,27 +117,36 @@ module IdentityCache
115
117
  !readonly
116
118
  end
117
119
 
118
- def should_use_cache? # :nodoc:
119
- ActiveRecord::Base.connection_handler.connection_pool_list(ActiveRecord::Base.current_role).none? do |pool|
120
- pool.active_connection? &&
121
- # Rails wraps each of your tests in a transaction, so that any changes
122
- # made to the database during the test can be rolled back afterwards.
123
- # These transactions are flagged as "unjoinable", which tries to make
124
- # your application behave as if they weren't there. In particular:
125
- #
126
- # - Opening another transaction during the test creates a savepoint,
127
- # which can be rolled back independently of the main transaction.
128
- # - When those nested transactions complete, any `after_commit`
129
- # callbacks for records modified during the transaction will run,
130
- # even though the changes haven't actually been committed yet.
131
- #
132
- # By ignoring unjoinable transactions, IdentityCache's behaviour
133
- # during your test suite will more closely match production.
134
- #
135
- # When there are no open transactions, `current_transaction` returns a
136
- # special `NullTransaction` object that is unjoinable, meaning we will
137
- # use the cache.
138
- pool.connection.current_transaction.joinable?
120
+ # Rails wraps each of your tests in a transaction, so that any changes
121
+ # made to the database during the test can be rolled back afterwards.
122
+ # These transactions are flagged as "unjoinable", which tries to make
123
+ # your application behave as if they weren't there. In particular:
124
+ #
125
+ # - Opening another transaction during the test creates a savepoint,
126
+ # which can be rolled back independently of the main transaction.
127
+ # - When those nested transactions complete, any `after_commit`
128
+ # callbacks for records modified during the transaction will run,
129
+ # even though the changes haven't actually been committed yet.
130
+ #
131
+ # By ignoring unjoinable transactions, IdentityCache's behaviour
132
+ # during your test suite will more closely match production.
133
+ #
134
+ # When there are no open transactions, `current_transaction` returns a
135
+ # special `NullTransaction` object that is unjoinable, meaning we will
136
+ # use the cache.
137
+ if ActiveRecord::ConnectionAdapters::ConnectionPool.method_defined?(:active_connection)
138
+ def should_use_cache? # :nodoc:
139
+ ActiveRecord::Base.connection_handler.connection_pool_list(ActiveRecord::Base.current_role).none? do |pool|
140
+ pool.active_connection? &&
141
+ pool.active_connection.current_transaction.joinable?
142
+ end
143
+ end
144
+ else
145
+ def should_use_cache? # :nodoc:
146
+ ActiveRecord::Base.connection_handler.connection_pool_list(ActiveRecord::Base.current_role).none? do |pool|
147
+ pool.active_connection? &&
148
+ pool.connection.current_transaction.joinable?
149
+ end
139
150
  end
140
151
  end
141
152
 
@@ -191,6 +202,44 @@ module IdentityCache
191
202
  result
192
203
  end
193
204
 
205
+ # Executes a block with deferred parent expiration, ensuring that the parent
206
+ # records' cache expiration is deferred until the block completes. When the block
207
+ # completes, it triggers expiration of the primary index for the parent records.
208
+ # Raises a NestedDeferredParentBlockError if a deferred parent expiration block
209
+ # is already active on the current thread.
210
+ #
211
+ # == Parameters:
212
+ # No parameters.
213
+ #
214
+ # == Raises:
215
+ # NestedDeferredParentBlockError if a deferred parent expiration block is already active.
216
+ #
217
+ # == Yield:
218
+ # Runs the provided block with deferred parent expiration.
219
+ #
220
+ # == Returns:
221
+ # The result of executing the provided block.
222
+ #
223
+ # == Ensures:
224
+ # Cleans up thread-local variables related to deferred parent expiration regardless
225
+ # of whether the block raises an exception.
226
+ def with_deferred_parent_expiration
227
+ raise NestedDeferredParentBlockError if Thread.current[:idc_deferred_parent_expiration]
228
+
229
+ Thread.current[:idc_deferred_parent_expiration] = true
230
+ Thread.current[:idc_parent_records_for_cache_expiry] = Set.new
231
+
232
+ result = yield
233
+
234
+ Thread.current[:idc_deferred_parent_expiration] = nil
235
+ Thread.current[:idc_parent_records_for_cache_expiry].each(&:expire_primary_index)
236
+
237
+ result
238
+ ensure
239
+ Thread.current[:idc_deferred_parent_expiration] = nil
240
+ Thread.current[:idc_parent_records_for_cache_expiry].clear
241
+ end
242
+
194
243
  def with_fetch_read_only_records(value = true)
195
244
  old_value = Thread.current[:identity_cache_fetch_read_only_records]
196
245
  Thread.current[:identity_cache_fetch_read_only_records] = value
data/shipit.rubygems.yml CHANGED
@@ -1 +1,4 @@
1
- # using the default shipit config
1
+ dependencies:
2
+ bundler:
3
+ without:
4
+ - default
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: identity_cache
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.6
4
+ version: 1.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Camilo Lopez
@@ -11,10 +11,10 @@ authors:
11
11
  - Tobias Lutke
12
12
  - Arthur Neves
13
13
  - Francis Bogsanyi
14
- autorequire:
14
+ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
- date: 2024-03-19 00:00:00.000000000 Z
17
+ date: 2024-08-21 00:00:00.000000000 Z
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
20
20
  name: activerecord
@@ -127,7 +127,6 @@ files:
127
127
  - gemfiles/Gemfile.min-supported
128
128
  - gemfiles/Gemfile.rails-edge
129
129
  - identity_cache.gemspec
130
- - isogun.yml
131
130
  - lib/identity_cache.rb
132
131
  - lib/identity_cache/belongs_to_caching.rb
133
132
  - lib/identity_cache/cache_fetcher.rb
@@ -177,7 +176,7 @@ homepage: https://github.com/Shopify/identity_cache
177
176
  licenses: []
178
177
  metadata:
179
178
  allowed_push_host: https://rubygems.org
180
- post_install_message:
179
+ post_install_message:
181
180
  rdoc_options: []
182
181
  require_paths:
183
182
  - lib
@@ -192,8 +191,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
192
191
  - !ruby/object:Gem::Version
193
192
  version: '0'
194
193
  requirements: []
195
- rubygems_version: 3.5.6
196
- signing_key:
194
+ rubygems_version: 3.5.17
195
+ signing_key:
197
196
  specification_version: 4
198
197
  summary: IdentityCache lets you specify how you want to cache your model objects,
199
198
  at the model level, and adds a number of convenience methods for accessing those
data/isogun.yml DELETED
@@ -1,11 +0,0 @@
1
- # https://dev-accel.shopify.io/dev/railgun/Railgun-Config
2
- name: identity-cache
3
-
4
- vm:
5
- ip_address: 192.168.64.98
6
- memory: 1G
7
- cores: 2
8
-
9
- services:
10
- - mysql
11
- - memcached