incrdecr_cached_counts 0.3.0 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 42bbe0c4b1d6ddc82d92bc3d1475dcf3e7553ef9f8299d0e3d75aa5d7c8519c6
4
- data.tar.gz: 652f35c8b0c667c3ee9517494c2a23b04ea3f90a7591d74922538c84906c754f
3
+ metadata.gz: 0d5bd60c008ad0b41a08214d9243ebb6278467bb3ca2b5f3314609c5361b6c1a
4
+ data.tar.gz: cea01587597deb81ff143e8383a194238a00e36c2e2529760aec60a83f485b5c
5
5
  SHA512:
6
- metadata.gz: 6610220977371d6bde5f48e6aa6dfbe879e4213d04fd0ae7bc05a00e4766751ee427b5e2f3e42ecb88fb8e665885a786f38a125a81fc042b258078e3a3debfa1
7
- data.tar.gz: 6d8c16611f42f680f4350b196935cf0caffef9253e6b016e1731b142f5d719c3ce43f2293869efb6393cb52f61e05e4819dfdac6357fccf4f228ff05111b3306
6
+ metadata.gz: a8e9a0efe389831ae4f8d28db0cc23f2b873c705231fed8caa80ee322e84abf0d0998f6f3d777a8e7ce565ce0c2770ab3438322ff50a2921349d3d9e4f81dac6
7
+ data.tar.gz: b8fdd83b366cc6827cf925bfb003a065a2139ab98a103b9cb2ad9daac89f421fd3110328d80e5c6910caa7ce9322c06791c67b3d64caf66c5d030e41cbdd1b35
data/.circleci/config.yml CHANGED
@@ -1,59 +1,47 @@
1
- version: 2
1
+ version: 2.1
2
2
 
3
3
  jobs:
4
4
  build:
5
5
  docker:
6
- - image: circleci/ruby:2.2
6
+ - image: cimg/ruby:2.7-node # use a tailored CircleCI docker image.
7
7
  steps:
8
8
  - checkout
9
9
 
10
+ - run: bundle config set path 'vendor/bundle'
11
+ - run: sudo apt-get update
12
+ - run: sudo apt install libsqlite3-dev
13
+
10
14
  # There's probably a better way of doing this that avoids the repetition and manual
11
15
  # deletion of Gemfile.lock.
12
16
  - restore_cache:
13
- key: rails-4.2.9-{{ checksum "Gemfile" }}
17
+ key: rails-5.2.4.4-{{ checksum "Gemfile" }}
14
18
  - run:
15
19
  name: bundle install
16
- command: bundle install --path vendor/bundle
20
+ command: bundle install
17
21
  environment:
18
- ACTIVERECORD_VERSION: 4.2.9
22
+ ACTIVERECORD_VERSION: 5.2.4.4
19
23
  - save_cache:
20
- key: rails-4.2.9-{{ checksum "Gemfile" }}
24
+ key: rails-5.2.4.4-{{ checksum "Gemfile" }}
21
25
  paths:
22
26
  - vendor/bundle
23
27
  - run:
24
- name: Test with Rails 4.2.9
28
+ name: Test with Rails 5.2
25
29
  command: bundle exec rspec
26
30
 
27
31
  - run: rm Gemfile.lock
28
32
  - restore_cache:
29
- key: rails-5.0.6-{{ checksum "Gemfile" }}
33
+ key: rails-6.0.3.4-{{ checksum "Gemfile" }}
30
34
  - run:
31
35
  name: bundle install
32
36
  command: bundle install --path vendor/bundle
33
37
  environment:
34
- ACTIVERECORD_VERSION: 5.0.6
38
+ ACTIVERECORD_VERSION: 6.0.3.4
35
39
  - save_cache:
36
- key: rails-5.0.6-{{ checksum "Gemfile" }}
40
+ key: rails-6.0.3.4-{{ checksum "Gemfile" }}
37
41
  paths:
38
42
  - vendor/bundle
39
43
  - restore_cache:
40
- key: rails-5.0.6-{{ checksum "Gemfile" }}
41
- - run:
42
- name: Test with Rails 5.0.6
43
- command: bundle exec rspec
44
-
45
- - run: rm Gemfile.lock
46
- - restore_cache:
47
- key: rails-5.1.4-{{ checksum "Gemfile" }}
48
- - run:
49
- name: bundle install
50
- command: bundle install --path vendor/bundle
51
- environment:
52
- ACTIVERECORD_VERSION: 5.1.4
53
- - save_cache:
54
- key: rails-5.1.4-{{ checksum "Gemfile" }}
55
- paths:
56
- - vendor/bundle
44
+ key: rails-6.0.3.4-{{ checksum "Gemfile" }}
57
45
  - run:
58
- name: Test with Rails 5.1.4
46
+ name: Test with Rails 6.0
59
47
  command: bundle exec rspec
@@ -19,13 +19,11 @@ Gem::Specification.new do |s|
19
19
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
20
  s.require_paths = ["lib"]
21
21
 
22
- s.add_dependency "rails", ">= 4.2"
22
+ s.add_dependency "rails", ">= 5.2"
23
23
  s.add_dependency "dalli"
24
24
 
25
25
  s.add_development_dependency "sqlite3"
26
26
  s.add_development_dependency "rspec"
27
27
  s.add_development_dependency "database_cleaner"
28
- s.add_development_dependency "test_after_commit"
29
- s.add_development_dependency "after_commit_exception_notification"
30
28
  s.add_development_dependency "rake"
31
29
  end
@@ -0,0 +1,21 @@
1
+ module CachedCounts
2
+ class << self
3
+ # Optional configuration: Set a proc which takes as arguments (1) the class
4
+ # we are counting and (2) the block that runs the count query. The
5
+ # `query_context` block must call the block that's passed as an argument.
6
+ #
7
+ # This is useful for replication, e.g.,
8
+ #
9
+ # CachedCounts.query_context = proc do |klass, &run_query|
10
+ # role = klass == User ? :reading : :writing
11
+ # ActiveRecord::Base.connected_to(role: role) do
12
+ # run_query.call
13
+ # end
14
+ # end
15
+ attr_writer :query_context
16
+
17
+ def query_context
18
+ @query_context ||= proc { |_klass, &block| block.call }
19
+ end
20
+ end
21
+ end
@@ -1,3 +1,3 @@
1
1
  module CachedCounts
2
- VERSION = "0.3.0"
2
+ VERSION = "0.6.0"
3
3
  end
data/lib/cached_counts.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  require 'cached_counts/logger'
2
- require 'cached_counts/dalli_check'
3
- require 'cached_counts/connection_for'
2
+ require 'cached_counts/query_context'
4
3
 
5
4
  module CachedCounts
6
5
  extend ActiveSupport::Concern
@@ -160,16 +159,6 @@ module CachedCounts
160
159
  fallback = Rails.cache.read(key)
161
160
  fallback = fallback.value if fallback.is_a?(ActiveSupport::Cache::Entry)
162
161
 
163
- if fallback.nil?
164
- begin
165
- fallback = relation.count
166
- rescue ActiveRecord::StatementInvalid => e
167
- fallback = 0
168
- end
169
-
170
- Rails.cache.write key, fallback, expires_in: options.fetch(:expires_in, 1.week), raw: true
171
- end
172
-
173
162
  -> { fallback }
174
163
  end
175
164
 
@@ -193,7 +182,7 @@ module CachedCounts
193
182
  ids.each do |id|
194
183
  result[id] = raw_result[association_count_key(id, attribute_name, version)]&.to_i || default
195
184
  end
196
-
185
+
197
186
  result
198
187
  end
199
188
 
@@ -254,24 +243,24 @@ module CachedCounts
254
243
  # Ensure that other reads find something in the cache, but
255
244
  # continue calculating here because the default is likely inaccurate.
256
245
  fallback_value = instance_exec &race_condition_fallback
257
- CachedCounts.logger.warn "Setting #{fallback_value} as race_condition_fallback for #{send(key_method)}"
258
- Rails.cache.write(
259
- send(key_method),
260
- fallback_value.to_i,
261
- expires_in: 30.seconds,
262
- raw: true
263
- )
246
+
247
+ if fallback_value
248
+ CachedCounts.logger.warn "Setting #{fallback_value} as race_condition_fallback for #{send(key_method)}"
249
+ Rails.cache.write(
250
+ send(key_method),
251
+ fallback_value.to_i,
252
+ expires_in: 30.seconds,
253
+ raw: true
254
+ )
255
+ end
264
256
  end
265
257
 
266
258
  relation = instance_exec(&relation_getter)
267
259
  relation = relation.reorder('')
268
260
  relation.select_values = ['count(*)']
269
261
 
270
- conn = CachedCounts.connection_for(counted_class)
271
- if Rails.version < '4.2'.freeze
272
- conn.select_value(relation.to_sql, nil, relation.values[:bind] || []).to_i
273
- else
274
- conn.select_value(relation.to_sql).to_i
262
+ CachedCounts.query_context.call(counted_class) do
263
+ counted_class.connection.select_value(relation.to_sql).to_i
275
264
  end
276
265
  end
277
266
 
data/spec/spec_helper.rb CHANGED
@@ -3,7 +3,7 @@ require 'bundler/setup'
3
3
  require 'pry'
4
4
  require 'active_record'
5
5
  require 'rails'
6
- require 'active_support/cache/dalli_store'
6
+ require 'active_support/cache/mem_cache_store'
7
7
  require 'cached_counts'
8
8
 
9
9
  ActiveRecord::Base.configurations = YAML::load_file('spec/database.yml')
@@ -13,7 +13,7 @@ if ActiveRecord::Base.respond_to?(:raise_in_transactional_callbacks)
13
13
  ActiveRecord::Base.raise_in_transactional_callbacks = true
14
14
  end
15
15
 
16
- Rails.cache = ActiveSupport::Cache::DalliStore.new("localhost")
16
+ Rails.cache = ActiveSupport::Cache::MemCacheStore.new("localhost")
17
17
 
18
18
  RSpec.configure do |config|
19
19
  config.before(:each) do
@@ -25,13 +25,6 @@ end
25
25
  require_relative './fixtures.rb'
26
26
  require 'database_cleaner'
27
27
 
28
- if Rails.version.to_f < 5.0
29
- require 'test_after_commit'
30
- end
31
- if Rails.version.to_f < 4.2
32
- require 'after_commit_exception_notification'
33
- end
34
-
35
28
  RSpec.configure do |config|
36
29
  config.before(:suite) do
37
30
  DatabaseCleaner.strategy = :transaction
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: incrdecr_cached_counts
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Judd
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-19 00:00:00.000000000 Z
11
+ date: 2022-07-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '4.2'
19
+ version: '5.2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '4.2'
26
+ version: '5.2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: dalli
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -80,34 +80,6 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: test_after_commit
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: after_commit_exception_notification
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
83
  - !ruby/object:Gem::Dependency
112
84
  name: rake
113
85
  requirement: !ruby/object:Gem::Requirement
@@ -132,7 +104,6 @@ extra_rdoc_files: []
132
104
  files:
133
105
  - ".circleci/config.yml"
134
106
  - ".gitignore"
135
- - ".travis.yml"
136
107
  - ".yardopts"
137
108
  - Gemfile
138
109
  - MIT-LICENSE
@@ -140,9 +111,8 @@ files:
140
111
  - Rakefile
141
112
  - incrdecr_cached_counts.gemspec
142
113
  - lib/cached_counts.rb
143
- - lib/cached_counts/connection_for.rb
144
- - lib/cached_counts/dalli_check.rb
145
114
  - lib/cached_counts/logger.rb
115
+ - lib/cached_counts/query_context.rb
146
116
  - lib/cached_counts/railtie.rb
147
117
  - lib/cached_counts/version.rb
148
118
  - spec/caches_count_of_spec.rb
@@ -173,17 +143,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
173
143
  - !ruby/object:Gem::Version
174
144
  version: '0'
175
145
  requirements: []
176
- rubygems_version: 3.0.3
146
+ rubygems_version: 3.1.4
177
147
  signing_key:
178
148
  specification_version: 4
179
149
  summary: A replacement for Rails' counter caches using memcached (via Dalli)
180
- test_files:
181
- - spec/caches_count_of_spec.rb
182
- - spec/caches_count_where_spec.rb
183
- - spec/database.yml
184
- - spec/fixtures.rb
185
- - spec/fixtures/department.rb
186
- - spec/fixtures/following.rb
187
- - spec/fixtures/university.rb
188
- - spec/fixtures/user.rb
189
- - spec/spec_helper.rb
150
+ test_files: []
data/.travis.yml DELETED
@@ -1,15 +0,0 @@
1
- sudo: false # use newer travis infrastructure
2
- language: ruby
3
- rvm:
4
- - "2.1.8"
5
- - "2.2.4"
6
- - "2.3.0"
7
- env:
8
- - "ACTIVERECORD_VERSION=4.2.6"
9
- - "ACTIVERECORD_VERSION=4.1.15"
10
- - "ACTIVERECORD_VERSION=4.0.13"
11
- - "ACTIVERECORD_VERSION=master"
12
- matrix:
13
- allow_failures:
14
- # Master may or may not pass
15
- - env: "ACTIVERECORD_VERSION=master"
@@ -1,14 +0,0 @@
1
- module CachedCounts
2
- class << self
3
- # Optional configuration: set a proc which takes the class we are counting
4
- # and returns a connection. Useful with replication, e.g. with Octopus:
5
- #
6
- # `CachedCounts.connection_for = proc { |klass| klass.using(:read_slave).connection }`
7
- attr_writer :connection_for
8
-
9
- def connection_for(counted_class)
10
- @connection_for ||= proc { |klass| klass.connection }
11
- @connection_for[counted_class]
12
- end
13
- end
14
- end
@@ -1,5 +0,0 @@
1
- if defined?(Rails)
2
- ActiveSupport.on_load :cached_counts do
3
- raise "CachedCounts depends on Dalli!" unless Rails.cache.respond_to?(:dalli)
4
- end
5
- end