cache_json 1.1.0 → 1.2.3

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: 4c98d70e39deec46936d9103a02a7e79abd094b829f53f7a1e9b203862b398ff
4
- data.tar.gz: a6e727b179329cc1dd68b8a15b2246c2028cef24f8148bba111b82bf84411d83
3
+ metadata.gz: d97faf1cadc565cb04a69dee9bd89df23574d72e9b8b412c2e55dffe201d88db
4
+ data.tar.gz: 69e444bf0badc19dc320d644ca4929712d23552537d6493845aab0cb682dff59
5
5
  SHA512:
6
- metadata.gz: 5aae4fbabd515f77747561abe2a427f2265cacb14376d085801bab836897fb79bc016be8ec1d4c4613c20af7705b8ef8cc1ed2d891db161008bb5feaca910f2d
7
- data.tar.gz: eac08115326cdbe40c10936a6d83e79df496ab4693d2fa414535b27217214fa3b1d79c2c0e7b9fb9e56abaf61329cb0a77b6226bf8d35f12ead8bcc6da6d8829
6
+ metadata.gz: 2eaae958e037c974bcc9b7042d35b75165c331976989dad8837aee846e60d176a81c4595971f174e5ba25d78f8af9c5fd2035743e0f2ebbbe49118cfbd741e8d
7
+ data.tar.gz: b6cd26c9c6e4318844be79eb4193af22318feabed40054e5d0b4b28c2cf705d3abd6c32927f5e6b4853eda4838c16ff07a6377b90ffbfd005eef94f378e0858f
@@ -1,14 +1,41 @@
1
- Style/GlobalVars:
2
- Enabled: false
3
-
4
- Style/Documentation:
5
- Enabled: false
1
+ Metrics/BlockLength:
2
+ Enabled: true
3
+ Exclude:
4
+ - "spec/**/*"
6
5
 
7
- Metrics/LineLength:
6
+ Layout/LineLength:
8
7
  Enabled: true
9
8
  Max: 100
10
9
 
11
- Metrics/BlockLength:
10
+ Layout/EmptyLinesAroundAttributeAccessor:
12
11
  Enabled: true
13
- Exclude:
14
- - "spec/**/*"
12
+
13
+ Layout/SpaceAroundMethodCallOperator:
14
+ Enabled: true
15
+
16
+ Lint/RaiseException:
17
+ Enabled: true
18
+
19
+ Lint/StructNewOverride:
20
+ Enabled: true
21
+
22
+ Style/ExponentialNotation:
23
+ Enabled: true
24
+
25
+ Style/HashEachMethods:
26
+ Enabled: true
27
+
28
+ Style/HashTransformKeys:
29
+ Enabled: true
30
+
31
+ Style/HashTransformValues:
32
+ Enabled: true
33
+
34
+ Style/SlicingWithRange:
35
+ Enabled: true
36
+
37
+ Style/GlobalVars:
38
+ Enabled: false
39
+
40
+ Style/Documentation:
41
+ Enabled: false
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cache_json (1.1.0)
4
+ cache_json (1.2.3)
5
5
  redis (>= 3.3.5, < 5)
6
6
 
7
7
  GEM
@@ -10,45 +10,47 @@ GEM
10
10
  ast (2.4.0)
11
11
  connection_pool (2.2.2)
12
12
  diff-lcs (1.3)
13
- jaro_winkler (1.5.3)
13
+ jaro_winkler (1.5.4)
14
14
  mock_redis (0.21.0)
15
- parallel (1.17.0)
16
- parser (2.6.3.0)
15
+ parallel (1.19.1)
16
+ parser (2.7.0.3)
17
17
  ast (~> 2.4.0)
18
- rack (2.0.7)
19
- rack-protection (2.0.5)
18
+ rack (2.2.3)
19
+ rack-protection (2.0.8.1)
20
20
  rack
21
21
  rainbow (3.0.0)
22
- rake (10.5.0)
23
- redis (4.1.2)
24
- rspec (3.8.0)
25
- rspec-core (~> 3.8.0)
26
- rspec-expectations (~> 3.8.0)
27
- rspec-mocks (~> 3.8.0)
28
- rspec-core (3.8.2)
29
- rspec-support (~> 3.8.0)
30
- rspec-expectations (3.8.4)
22
+ rake (13.0.1)
23
+ redis (4.1.3)
24
+ rexml (3.2.4)
25
+ rspec (3.9.0)
26
+ rspec-core (~> 3.9.0)
27
+ rspec-expectations (~> 3.9.0)
28
+ rspec-mocks (~> 3.9.0)
29
+ rspec-core (3.9.1)
30
+ rspec-support (~> 3.9.1)
31
+ rspec-expectations (3.9.0)
31
32
  diff-lcs (>= 1.2.0, < 2.0)
32
- rspec-support (~> 3.8.0)
33
- rspec-mocks (3.8.1)
33
+ rspec-support (~> 3.9.0)
34
+ rspec-mocks (3.9.1)
34
35
  diff-lcs (>= 1.2.0, < 2.0)
35
- rspec-support (~> 3.8.0)
36
- rspec-support (3.8.2)
37
- rubocop (0.72.0)
36
+ rspec-support (~> 3.9.0)
37
+ rspec-support (3.9.2)
38
+ rubocop (0.80.1)
38
39
  jaro_winkler (~> 1.5.1)
39
40
  parallel (~> 1.10)
40
- parser (>= 2.6)
41
+ parser (>= 2.7.0.1)
41
42
  rainbow (>= 2.2.2, < 4.0)
43
+ rexml
42
44
  ruby-progressbar (~> 1.7)
43
45
  unicode-display_width (>= 1.4.0, < 1.7)
44
46
  ruby-progressbar (1.10.1)
45
- sidekiq (5.2.7)
46
- connection_pool (~> 2.2, >= 2.2.2)
47
- rack (>= 1.5.0)
48
- rack-protection (>= 1.5.0)
49
- redis (>= 3.3.5, < 5)
47
+ sidekiq (6.0.5)
48
+ connection_pool (>= 2.2.2)
49
+ rack (~> 2.0)
50
+ rack-protection (>= 2.0.0)
51
+ redis (>= 4.1.0)
50
52
  timecop (0.9.1)
51
- unicode-display_width (1.6.0)
53
+ unicode-display_width (1.6.1)
52
54
 
53
55
  PLATFORMS
54
56
  ruby
@@ -57,11 +59,11 @@ DEPENDENCIES
57
59
  bundler (~> 2.0)
58
60
  cache_json!
59
61
  mock_redis (~> 0.21.0)
60
- rake (~> 10.0)
62
+ rake (~> 13.0)
61
63
  rspec (~> 3.0)
62
64
  rubocop (~> 0.72)
63
65
  sidekiq (>= 3.0, < 7)
64
66
  timecop (~> 0.9.1)
65
67
 
66
68
  BUNDLED WITH
67
- 2.0.2
69
+ 2.1.4
data/README.md CHANGED
@@ -54,6 +54,43 @@ CacheJSON.configure do |config|
54
54
  end
55
55
  ```
56
56
 
57
+ ## Automatic refreshing (Sidekiq)
58
+
59
+ There is a simple Sidekiq job that lets you pre-compute selected classes with specified ranges of arguments. All you have to do is add a `refresh` option:
60
+
61
+ ```ruby
62
+ class ExpensiveJob
63
+
64
+ include CacheJSON::Base
65
+
66
+
67
+ cache_json_options(
68
+ time_to_expire: 1.hour,
69
+ refresh: {
70
+ arguments: {
71
+ first: (5..10),
72
+ second: ['one option', 'another option'],
73
+ third: 'the only option',
74
+ fourth: -> { ['proc result'] }
75
+ }
76
+ }
77
+ )
78
+ ...
79
+ end
80
+ ```
81
+
82
+ The Sidekiq job will take the Cartesian product of all the argument ranges/arrays (all the combinations).
83
+
84
+ We leave it to you to schedule the job. If you're using https://github.com/moove-it/sidekiq-scheduler, you can do something like this:
85
+
86
+ ```yml
87
+ cache_json_worker:
88
+ every: "20s"
89
+ class: CacheJSON::Worker
90
+ ```
91
+
92
+ Whenever the worker runs, it checks which results have expired, and refreshes only those.
93
+
57
94
  ## Development
58
95
 
59
96
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -30,7 +30,7 @@ Gem::Specification.new do |spec|
30
30
  spec.add_dependency 'redis', '>= 3.3.5', '< 5'
31
31
  spec.add_development_dependency 'bundler', '~> 2.0'
32
32
  spec.add_development_dependency 'mock_redis', '~> 0.21.0'
33
- spec.add_development_dependency 'rake', '~> 10.0'
33
+ spec.add_development_dependency 'rake', '~> 13.0'
34
34
  spec.add_development_dependency 'rspec', '~> 3.0'
35
35
  spec.add_development_dependency 'rubocop', '~> 0.72'
36
36
  spec.add_development_dependency 'sidekiq', '>= 3.0', '< 7'
@@ -8,7 +8,7 @@ module CacheJSON
8
8
  base.extend(ClassMethods)
9
9
  end
10
10
 
11
- def results(args)
11
+ def results(args = {})
12
12
  raise ArgumentError, 'Must use keyword arguments' unless args.is_a?(Hash)
13
13
 
14
14
  options = self.class.cache_json_full_options
@@ -23,7 +23,7 @@ module CacheJSON
23
23
 
24
24
  def refresh_cache!(args:, cache: nil)
25
25
  cache ||= Cache.new(args: args, options: self.class.cache_json_full_options)
26
- results = compute_results(args)
26
+ results = compute_results(**args)
27
27
  cache.cached_results = results
28
28
  results
29
29
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CacheJSON
4
- VERSION = '1.1.0'
4
+ VERSION = '1.2.3'
5
5
  end
@@ -22,60 +22,71 @@ module CacheJSON
22
22
  if klass
23
23
  klass.new.refresh_cache!(args: args)
24
24
  else
25
- generate_workers
25
+ AllPermutations.new.results.each do |perm|
26
+ if should_refresh?(perm[:klass], perm[:args])
27
+ CacheJSON::Worker.new.perform(klass: perm[:klass], args: perm[:args])
28
+ end
29
+ end
26
30
  end
27
31
  end
28
32
 
29
33
  private
30
34
 
31
- def generate_workers
32
- all_cache_classes.each do |klass|
33
- all_argument_permutations(klass).each do |args|
34
- CacheJSON::Worker.new.perform(klass: klass, args: args) if should_refresh?(klass, args)
35
- end
36
- end
35
+ def should_refresh?(klass, args)
36
+ !klass.new.check_cache(args: args)
37
37
  end
38
38
 
39
- def all_cache_classes
40
- # TODO: make this more efficient
41
- ObjectSpace.each_object(Class).select do |klass|
42
- klass.included_modules.include? CacheJSON::Base
39
+ class AllPermutations
40
+ def results
41
+ all_cache_classes.flat_map do |klass|
42
+ all_argument_permutations(klass).map do |args|
43
+ {
44
+ klass: klass,
45
+ args: args
46
+ }
47
+ end
48
+ end
43
49
  end
44
- end
45
50
 
46
- def all_argument_permutations(klass)
47
- refresh_options = klass.cache_json_full_options[:refresh]
48
- if refresh_options
49
- all_combinations_with_fixed_points({}, refresh_options[:arguments])
50
- else
51
- []
51
+ def all_cache_classes
52
+ # TODO: make this more efficient
53
+ ObjectSpace.each_object(Class).select do |klass|
54
+ klass.included_modules.include? CacheJSON::Base
55
+ end
52
56
  end
53
- end
54
57
 
55
- def all_combinations_with_fixed_points(fixed_points, full_hash)
56
- non_fixed_points = full_hash.dup.delete_if { |k, _| fixed_points.key?(k) }
57
- if non_fixed_points.empty?
58
- [fixed_points]
59
- else
60
- pivot_key = non_fixed_points.keys.first
61
- values_for_key(non_fixed_points, pivot_key).flat_map do |pivot_key_value|
62
- new_fixed_points = fixed_points.merge(Hash[pivot_key, pivot_key_value])
63
- all_combinations_with_fixed_points(new_fixed_points, full_hash)
58
+ def all_argument_permutations(klass)
59
+ refresh_options = klass.cache_json_full_options[:refresh]
60
+ if refresh_options
61
+ all_combinations_with_fixed_points({}, refresh_options[:arguments])
62
+ else
63
+ []
64
64
  end
65
65
  end
66
- end
67
66
 
68
- def values_for_key(hsh, key)
69
- pivot_key_values = hsh[key]
70
- if pivot_key_values.is_a?(Range) || pivot_key_values.is_a?(Array)
71
- pivot_key_values
72
- else
73
- [pivot_key_values]
67
+ def all_combinations_with_fixed_points(fixed_points, full_hash)
68
+ non_fixed_points = full_hash.dup.delete_if { |k, _| fixed_points.key?(k) }
69
+ if non_fixed_points.empty?
70
+ [fixed_points]
71
+ else
72
+ pivot_key = non_fixed_points.keys.first
73
+ values_for_key(non_fixed_points, pivot_key).flat_map do |pivot_key_value|
74
+ new_fixed_points = fixed_points.merge(Hash[pivot_key, pivot_key_value])
75
+ all_combinations_with_fixed_points(new_fixed_points, full_hash)
76
+ end
77
+ end
74
78
  end
75
- end
76
79
 
77
- def should_refresh?(klass, args)
78
- !klass.new.check_cache(args: args)
80
+ def values_for_key(hsh, key)
81
+ pivot_key_values = hsh[key]
82
+ if pivot_key_values.is_a?(Proc)
83
+ pivot_key_values.call
84
+ elsif pivot_key_values.is_a?(Range) || pivot_key_values.is_a?(Array)
85
+ pivot_key_values
86
+ else
87
+ [pivot_key_values]
88
+ end
89
+ end
79
90
  end
80
91
  end
81
92
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cache_json
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Gut
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-07-15 00:00:00.000000000 Z
11
+ date: 2020-10-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -64,14 +64,14 @@ dependencies:
64
64
  requirements:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
- version: '10.0'
67
+ version: '13.0'
68
68
  type: :development
69
69
  prerelease: false
70
70
  version_requirements: !ruby/object:Gem::Requirement
71
71
  requirements:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
- version: '10.0'
74
+ version: '13.0'
75
75
  - !ruby/object:Gem::Dependency
76
76
  name: rspec
77
77
  requirement: !ruby/object:Gem::Requirement
@@ -181,7 +181,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
181
181
  - !ruby/object:Gem::Version
182
182
  version: '0'
183
183
  requirements: []
184
- rubygems_version: 3.0.3
184
+ rubygems_version: 3.1.2
185
185
  signing_key:
186
186
  specification_version: 4
187
187
  summary: Extremely simple Redis caching for any Ruby class