incrdecr_cached_counts 0.0.6 → 0.4.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
- SHA1:
3
- metadata.gz: a018b5815304845fe6bd35505944da125418b3e5
4
- data.tar.gz: c1799c3ddaa64683faf943ea9e0d352177c896f0
2
+ SHA256:
3
+ metadata.gz: b1abd3ec58583d46e713effab128bece6d90b4799261cb5714981e8e545a293b
4
+ data.tar.gz: 435c1c883ba00f766473e563732602245e5a1680f92bbc852251ce48497bab53
5
5
  SHA512:
6
- metadata.gz: d4ae781d8e7394523beb4f91cbb622f018bc9ee30a04a92cbd4e00e7bdecbeb87f93c9f87dacc6b27a41872c1b1b64f97349a4ecfb1a89043345922a8f57b699
7
- data.tar.gz: d52e2154bc2bd201b8297b9ca32cd4b142f1a265e2f7f89b8df3b86aa4c0b8ccd79ecf76e847da13c0f86389ca017ef465ae501d330a22653fb13521e73e1862
6
+ metadata.gz: 870a0f140a0d815f1e2e824ae5c9cd802cfcab3be446f376ad2f08f80ff2eadd560d899a7f85cfd099d08a2ffbc517beeb5926575cae557e5a68c2d3d9bb79e8
7
+ data.tar.gz: 6f6058c68108b32c94e3d6c4be7d785974371f21b7fd828f4df9a5b33d108912537ed102685bb2601aac5e3267a32ea27d4a65508721c0ca5cb5566e44aac1f5
@@ -0,0 +1,47 @@
1
+ version: 2.1
2
+
3
+ jobs:
4
+ build:
5
+ docker:
6
+ - image: cimg/ruby:2.7-node # use a tailored CircleCI docker image.
7
+ steps:
8
+ - checkout
9
+
10
+ - run: bundle config set path 'vendor/bundle'
11
+ - run: sudo apt-get update
12
+ - run: sudo apt install libsqlite3-dev
13
+
14
+ # There's probably a better way of doing this that avoids the repetition and manual
15
+ # deletion of Gemfile.lock.
16
+ - restore_cache:
17
+ key: rails-5.2.4.4-{{ checksum "Gemfile" }}
18
+ - run:
19
+ name: bundle install
20
+ command: bundle install
21
+ environment:
22
+ ACTIVERECORD_VERSION: 5.2.4.4
23
+ - save_cache:
24
+ key: rails-5.2.4.4-{{ checksum "Gemfile" }}
25
+ paths:
26
+ - vendor/bundle
27
+ - run:
28
+ name: Test with Rails 5.2
29
+ command: bundle exec rspec
30
+
31
+ - run: rm Gemfile.lock
32
+ - restore_cache:
33
+ key: rails-6.0.3.4-{{ checksum "Gemfile" }}
34
+ - run:
35
+ name: bundle install
36
+ command: bundle install --path vendor/bundle
37
+ environment:
38
+ ACTIVERECORD_VERSION: 6.0.3.4
39
+ - save_cache:
40
+ key: rails-6.0.3.4-{{ checksum "Gemfile" }}
41
+ paths:
42
+ - vendor/bundle
43
+ - restore_cache:
44
+ key: rails-6.0.3.4-{{ checksum "Gemfile" }}
45
+ - run:
46
+ name: Test with Rails 6.0
47
+ command: bundle exec rspec
@@ -1,5 +1,7 @@
1
1
  = CachedCounts
2
2
 
3
+ {<img src="http://circleci.com/gh/academia-edu/cached_counts.svg?style=svg" />}[https://circleci.com/gh/academia-edu/cached_counts]
4
+
3
5
  A replacement for Rails' counter caches, using memcached.
4
6
 
5
7
  Caches counts of models in a scope or association in memcached, and keeps the
@@ -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.0"
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
@@ -1,6 +1,6 @@
1
1
  require 'cached_counts/logger'
2
2
  require 'cached_counts/dalli_check'
3
- require 'cached_counts/connection_for'
3
+ require 'cached_counts/query_context'
4
4
 
5
5
  module CachedCounts
6
6
  extend ActiveSupport::Concern
@@ -185,6 +185,18 @@ module CachedCounts
185
185
  association_count_key(id, attribute_name, version)
186
186
  end
187
187
 
188
+ # Try to fetch values for ids from the cache. If it's a miss return the default value
189
+ define_singleton_method "try_#{attr_name}_counts_for" do |ids, default=nil|
190
+ raw_result = Rails.cache.read_multi(*ids.map{|id| association_count_key(id, attribute_name, version)})
191
+
192
+ result = {}
193
+ ids.each do |id|
194
+ result[id] = raw_result[association_count_key(id, attribute_name, version)]&.to_i || default
195
+ end
196
+
197
+ result
198
+ end
199
+
188
200
  define_singleton_method "#{attr_name}_count_for" do |id|
189
201
  new({id: id}, without_protection: true).send("#{attr_name}_count")
190
202
  end
@@ -255,11 +267,8 @@ module CachedCounts
255
267
  relation = relation.reorder('')
256
268
  relation.select_values = ['count(*)']
257
269
 
258
- conn = CachedCounts.connection_for(counted_class)
259
- if Rails.version < '4.2'.freeze
260
- conn.select_value(relation.to_sql, nil, relation.values[:bind] || []).to_i
261
- else
262
- conn.select_value(relation.to_sql).to_i
270
+ CachedCounts.query_context.call(counted_class) do
271
+ counted_class.connection.select_value(relation.to_sql).to_i
263
272
  end
264
273
  end
265
274
 
@@ -285,7 +294,7 @@ module CachedCounts
285
294
  end
286
295
 
287
296
  def add_counting_hooks(attribute_name, key_getter, counted_class, options)
288
- increment_hook = "increment_#{attribute_name}_count"
297
+ increment_hook = "increment_#{attribute_name}_count".to_sym
289
298
  counted_class.send :define_method, increment_hook do
290
299
  if (key = instance_exec &key_getter)
291
300
  Rails.cache.increment(
@@ -296,7 +305,7 @@ module CachedCounts
296
305
  end
297
306
  end
298
307
 
299
- decrement_hook = "decrement_#{attribute_name}_count"
308
+ decrement_hook = "decrement_#{attribute_name}_count".to_sym
300
309
  counted_class.send :define_method, decrement_hook do
301
310
  if (key = instance_exec &key_getter)
302
311
  Rails.cache.decrement(
@@ -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.0.6"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -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.0.6
4
+ version: 0.4.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: 2016-06-23 00:00:00.000000000 Z
11
+ date: 2020-11-25 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.0'
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.0'
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
@@ -130,20 +102,18 @@ executables: []
130
102
  extensions: []
131
103
  extra_rdoc_files: []
132
104
  files:
133
- - ".circleci-matrix.yml"
105
+ - ".circleci/config.yml"
134
106
  - ".gitignore"
135
- - ".travis.yml"
136
107
  - ".yardopts"
137
108
  - Gemfile
138
109
  - MIT-LICENSE
139
110
  - README.rdoc
140
111
  - Rakefile
141
- - circle.yml
142
112
  - incrdecr_cached_counts.gemspec
143
113
  - lib/cached_counts.rb
144
- - lib/cached_counts/connection_for.rb
145
114
  - lib/cached_counts/dalli_check.rb
146
115
  - lib/cached_counts/logger.rb
116
+ - lib/cached_counts/query_context.rb
147
117
  - lib/cached_counts/railtie.rb
148
118
  - lib/cached_counts/version.rb
149
119
  - spec/caches_count_of_spec.rb
@@ -174,19 +144,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
174
144
  - !ruby/object:Gem::Version
175
145
  version: '0'
176
146
  requirements: []
177
- rubyforge_project:
178
- rubygems_version: 2.4.5.1
147
+ rubygems_version: 3.1.4
179
148
  signing_key:
180
149
  specification_version: 4
181
150
  summary: A replacement for Rails' counter caches using memcached (via Dalli)
182
- test_files:
183
- - spec/caches_count_of_spec.rb
184
- - spec/caches_count_where_spec.rb
185
- - spec/database.yml
186
- - spec/fixtures.rb
187
- - spec/fixtures/department.rb
188
- - spec/fixtures/following.rb
189
- - spec/fixtures/university.rb
190
- - spec/fixtures/user.rb
191
- - spec/spec_helper.rb
192
- has_rdoc:
151
+ test_files: []
@@ -1,8 +0,0 @@
1
- env:
2
- - ACTIVERECORD_VERSION=4.2.6
3
- - ACTIVERECORD_VERSION=4.1.15
4
- - ACTIVERECORD_VERSION=4.0.13
5
-
6
- command:
7
- - rm -f Gemfile.lock && ACTIVERECORD_VERSION=$ACTIVERECORD_VERSION bundle
8
- - bundle exec rake
@@ -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"
data/circle.yml DELETED
@@ -1,10 +0,0 @@
1
- machine:
2
- ruby:
3
- version: 2.2.3
4
-
5
- dependencies:
6
- pre:
7
- - curl -fsSL https://git.io/v2Ifn | bash
8
-
9
- database:
10
- override:
@@ -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