thermos 0.2.0 → 0.4.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: 04efdd478f71c4f4fe74081f47897d5697f31de2a8da87ec518576a95eb73ce5
4
- data.tar.gz: 12ee9eeb685234e02ed3525f30d98ecb2862b4a4a0906f9eaacdd8eb1ff61f2f
3
+ metadata.gz: e8a6fdb2b9baf6513ed750de28354540a73231dad66cf99d6de39ccfd74debc7
4
+ data.tar.gz: 0a5de531cb59a1c4b9b86e3875fffd78df0b1bb242fc2ec39ac1b740772cc360
5
5
  SHA512:
6
- metadata.gz: 4869f239ad783a58f7aa8a51868eeb402ed2f8cf580a8db79e856effccdcad4760e3478dde841d822780cb578904e4ef059a16e1099d2c460fd217d58243fa2c
7
- data.tar.gz: 634e49aab91d581c16586708880ae710f4340ca7d778bb38ff61cc8d8ad5790b0835c402d2dbe73cce1f76ace6ee224c42850c2678de187a3b98afc4c9424e99
6
+ metadata.gz: b1b7efff2c5be5ed8f93c5a7649f4804c8f3fca74a8a77e6a64065017545bec2f22ade70ebdbe41bb548c419179b3e6755877341a172a078ed8466ca3dcf7dd2
7
+ data.tar.gz: 2c09712783766bdfb3960660af31ee5a9806e707e49080fc4b677c3d8566cb1e01f582b37cd263023c9b0dcf4be7b2641248f9d6a8cb43450545a00fd177ca7a
data/lib/thermos.rb CHANGED
@@ -8,14 +8,14 @@ require 'thermos/refill_job'
8
8
  require 'thermos/rebuild_cache_job'
9
9
 
10
10
  module Thermos
11
- def self.keep_warm(key:, model:, id:, deps: [], lookup_key: nil, &block)
12
- fill(key: key, model: model, deps: deps, lookup_key: lookup_key, &block)
11
+ def self.keep_warm(key:, model:, id:, deps: [], lookup_key: nil, filter: nil, &block)
12
+ fill(key: key, model: model, deps: deps, lookup_key: lookup_key, filter: filter, &block)
13
13
  drink(key: key, id: id)
14
14
  end
15
15
 
16
- def self.fill(key:, model:, deps: [], lookup_key: nil, &block)
16
+ def self.fill(key:, model:, deps: [], lookup_key: nil, filter: nil, &block)
17
17
  BeverageStorage.instance.add_beverage(
18
- Beverage.new(key: key, model: model, deps: deps, action: block, lookup_key: lookup_key)
18
+ Beverage.new(key: key, model: model, deps: deps, action: block, lookup_key: lookup_key, filter: filter)
19
19
  )
20
20
  end
21
21
 
@@ -2,12 +2,13 @@
2
2
 
3
3
  module Thermos
4
4
  class Beverage
5
- attr_reader :key, :model, :deps, :action, :lookup_key
5
+ attr_reader :key, :model, :deps, :action, :lookup_key, :filter
6
6
 
7
- def initialize(key:, model:, deps:, action:, lookup_key: nil)
7
+ def initialize(key:, model:, deps:, action:, lookup_key: nil, filter: nil)
8
8
  @key = key
9
9
  @model = model
10
10
  @lookup_key = lookup_key || :id
11
+ @filter = filter || nil
11
12
  @deps = deps.map do |dep|
12
13
  Dependency.new(model: model, association: dep)
13
14
  end
@@ -17,14 +18,19 @@ module Thermos
17
18
  end
18
19
 
19
20
  def lookup_keys_for_dep_model(dep_model)
20
- @deps.flat_map do |dep|
21
- return [] unless dep.klass == dep_model.class
21
+ @deps.select do |dep|
22
+ dep.klass == dep_model.class
23
+ end.flat_map do |dep|
22
24
  @model.joins(dep.association)
23
25
  .where(dep.table => { id: dep_model.id })
24
26
  .pluck(@lookup_key)
25
27
  end.uniq
26
28
  end
27
29
 
30
+ def should_fill?(model)
31
+ @filter.class == Proc ? !!@filter.call(model) : true
32
+ end
33
+
28
34
  private
29
35
 
30
36
  def set_observers
@@ -5,7 +5,7 @@ module Thermos
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
8
- after_save :notify_thermos
8
+ after_commit :notify_thermos
9
9
  end
10
10
 
11
11
  private
@@ -9,7 +9,7 @@ module Thermos
9
9
 
10
10
  def refill_primary_caches(model)
11
11
  BeverageStorage.instance.beverages.each do |beverage|
12
- if beverage.model == model.class
12
+ if beverage.model == model.class && beverage.should_fill?(model)
13
13
  Thermos::RebuildCacheJob.perform_later(beverage.key, model.send(beverage.lookup_key))
14
14
  end
15
15
  end
@@ -17,8 +17,10 @@ module Thermos
17
17
 
18
18
  def refill_dependency_caches(model)
19
19
  BeverageStorage.instance.beverages.each do |beverage|
20
- beverage.lookup_keys_for_dep_model(model).each do |lookup_key|
21
- Thermos::RebuildCacheJob.perform_later(beverage.key, lookup_key)
20
+ if beverage.should_fill?(model)
21
+ beverage.lookup_keys_for_dep_model(model).each do |lookup_key|
22
+ Thermos::RebuildCacheJob.perform_later(beverage.key, lookup_key)
23
+ end
22
24
  end
23
25
  end
24
26
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Thermos
4
- VERSION = '0.2.0'
4
+ VERSION = '0.4.1'
5
5
  end
@@ -0,0 +1,3 @@
1
+ //= link_tree ../images
2
+ //= link_directory ../javascripts .js
3
+ //= link_directory ../stylesheets .css
@@ -18,10 +18,6 @@ module Dummy
18
18
  # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
19
19
  # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
20
20
  # config.i18n.default_locale = :de
21
-
22
- if Rails.version >= "5.2.0"
23
- Rails.application.config.active_record.sqlite3.represent_boolean_as_integer = true
24
- end
25
21
  end
26
22
  end
27
23
 
@@ -2,11 +2,11 @@
2
2
  # of editing this file, please use the migrations feature of Active Record to
3
3
  # incrementally modify your database, and then regenerate this schema definition.
4
4
  #
5
- # Note that this schema.rb definition is the authoritative source for your
6
- # database schema. If you need to create the application database on another
7
- # system, you should be using db:schema:load, not running all the migrations
8
- # from scratch. The latter is a flawed and unsustainable approach (the more migrations
9
- # you'll amass, the slower it'll run and the greater likelihood for issues).
5
+ # This file is the source Rails uses to define your schema when running `bin/rails
6
+ # db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
7
+ # be faster and is potentially less error prone than running all of your
8
+ # migrations from scratch. Old migrations may fail to apply correctly if those
9
+ # migrations use external dependencies or application code.
10
10
  #
11
11
  # It's strongly recommended that you check this file into your version control system.
12
12
 
data/test/thermos_test.rb CHANGED
@@ -65,6 +65,30 @@ class ThermosTest < ActiveSupport::TestCase
65
65
  assert_raises(MockExpectationError) { mock.verify }
66
66
  end
67
67
 
68
+ test "does not rebuild the cache on rolled back primary model change" do
69
+ mock = Minitest::Mock.new
70
+ category = categories(:baseball)
71
+
72
+ Thermos.fill(key: "key", model: Category) do |id|
73
+ mock.call(id)
74
+ end
75
+
76
+ mock.expect(:call, 1, [category.id])
77
+ assert_equal 1, Thermos.drink(key: "key", id: category.id)
78
+ mock.verify
79
+
80
+ mock.expect(:call, 2, [category.id])
81
+ ActiveRecord::Base.transaction do
82
+ category.update!(name: "foo")
83
+ raise ActiveRecord::Rollback
84
+ end
85
+ assert_raises(MockExpectationError) { mock.verify }
86
+
87
+ mock.expect(:call, 3, [category.id])
88
+ assert_equal 1, Thermos.drink(key: "key", id: category.id)
89
+ assert_raises(MockExpectationError) { mock.verify }
90
+ end
91
+
68
92
  test "does not rebuild the cache for an unrelated primary model change" do
69
93
  mock = Minitest::Mock.new
70
94
  category = categories(:baseball)
@@ -102,6 +126,23 @@ class ThermosTest < ActiveSupport::TestCase
102
126
  assert_equal 1, Thermos.drink(key: "key", id: "foo")
103
127
  assert_raises(MockExpectationError) { mock.verify }
104
128
  end
129
+
130
+ test "allows filtering for which records should be rebuilt" do
131
+ mock = Minitest::Mock.new
132
+ category = categories(:baseball)
133
+ filter = ->(model) { model.name.match("ball") }
134
+ Thermos.fill(key: "key", model: Category, lookup_key: "name", filter: filter) do |name|
135
+ mock.call(name)
136
+ end
137
+
138
+ mock.expect(:call, 1, ["basketball"])
139
+ category.update!(name: "basketball")
140
+ mock.verify
141
+
142
+ mock.expect(:call, 1, ["hockey"])
143
+ category.update!(name: "hockey")
144
+ assert_raises(MockExpectationError) { mock.verify }
145
+ end
105
146
 
106
147
  # has_many model changes
107
148
  test "rebuilds the cache on has_many model change" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thermos
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Thal
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-12-30 00:00:00.000000000 Z
11
+ date: 2021-07-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -16,14 +16,20 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 5.0.0
19
+ version: 5.2.4
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: 6.2.0
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
27
  - - ">="
25
28
  - !ruby/object:Gem::Version
26
- version: 5.0.0
29
+ version: 5.2.4
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: 6.2.0
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: rake
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -73,6 +79,7 @@ files:
73
79
  - lib/thermos/version.rb
74
80
  - test/dummy/README.rdoc
75
81
  - test/dummy/Rakefile
82
+ - test/dummy/app/assets/config/manifest.js
76
83
  - test/dummy/app/assets/javascripts/application.js
77
84
  - test/dummy/app/assets/stylesheets/application.css
78
85
  - test/dummy/app/controllers/application_controller.rb
@@ -133,63 +140,67 @@ required_ruby_version: !ruby/object:Gem::Requirement
133
140
  - - ">="
134
141
  - !ruby/object:Gem::Version
135
142
  version: 2.5.0
143
+ - - "<"
144
+ - !ruby/object:Gem::Version
145
+ version: 2.8.0
136
146
  required_rubygems_version: !ruby/object:Gem::Requirement
137
147
  requirements:
138
148
  - - ">="
139
149
  - !ruby/object:Gem::Version
140
150
  version: '0'
141
151
  requirements: []
142
- rubygems_version: 3.0.3
152
+ rubygems_version: 3.0.3.1
143
153
  signing_key:
144
154
  specification_version: 4
145
155
  summary: Always-warm, auto-rebuilding rails caching without timers or touching.
146
156
  test_files:
147
- - test/fixtures/category_items.yml
157
+ - test/thermos_test.rb
148
158
  - test/fixtures/categories.yml
149
- - test/fixtures/stores.yml
150
159
  - test/fixtures/products.yml
160
+ - test/fixtures/stores.yml
161
+ - test/fixtures/category_items.yml
162
+ - test/dummy/README.rdoc
163
+ - test/dummy/config.ru
164
+ - test/dummy/Rakefile
165
+ - test/dummy/db/schema.rb
166
+ - test/dummy/db/migrate/20160325214744_create_categories.rb
167
+ - test/dummy/db/migrate/20160326174530_create_stores.rb
168
+ - test/dummy/db/migrate/20160325214849_create_products.rb
169
+ - test/dummy/db/migrate/20160325220006_create_category_items.rb
170
+ - test/dummy/config/environment.rb
171
+ - test/dummy/config/secrets.yml
151
172
  - test/dummy/config/application.rb
173
+ - test/dummy/config/environments/test.rb
174
+ - test/dummy/config/environments/development.rb
175
+ - test/dummy/config/environments/production.rb
152
176
  - test/dummy/config/boot.rb
153
- - test/dummy/config/routes.rb
154
177
  - test/dummy/config/locales/en.yml
155
- - test/dummy/config/initializers/backtrace_silencers.rb
178
+ - test/dummy/config/database.yml
156
179
  - test/dummy/config/initializers/cookies_serializer.rb
157
- - test/dummy/config/initializers/wrap_parameters.rb
180
+ - test/dummy/config/initializers/assets.rb
181
+ - test/dummy/config/initializers/backtrace_silencers.rb
182
+ - test/dummy/config/initializers/mime_types.rb
158
183
  - test/dummy/config/initializers/session_store.rb
184
+ - test/dummy/config/initializers/wrap_parameters.rb
159
185
  - test/dummy/config/initializers/filter_parameter_logging.rb
160
- - test/dummy/config/initializers/assets.rb
161
186
  - test/dummy/config/initializers/inflections.rb
162
- - test/dummy/config/initializers/mime_types.rb
163
- - test/dummy/config/secrets.yml
164
- - test/dummy/config/environment.rb
165
- - test/dummy/config/database.yml
166
- - test/dummy/config/environments/development.rb
167
- - test/dummy/config/environments/production.rb
168
- - test/dummy/config/environments/test.rb
169
- - test/dummy/bin/setup
170
- - test/dummy/bin/rails
171
- - test/dummy/bin/bundle
172
- - test/dummy/bin/rake
173
- - test/dummy/app/views/layouts/application.html.erb
174
- - test/dummy/app/models/store.rb
175
- - test/dummy/app/models/category.rb
176
- - test/dummy/app/models/product.rb
187
+ - test/dummy/config/routes.rb
188
+ - test/dummy/public/500.html
189
+ - test/dummy/public/404.html
190
+ - test/dummy/public/422.html
191
+ - test/dummy/public/favicon.ico
177
192
  - test/dummy/app/models/category_item.rb
178
- - test/dummy/app/assets/stylesheets/application.css
193
+ - test/dummy/app/models/product.rb
194
+ - test/dummy/app/models/category.rb
195
+ - test/dummy/app/models/store.rb
196
+ - test/dummy/app/helpers/application_helper.rb
197
+ - test/dummy/app/views/layouts/application.html.erb
179
198
  - test/dummy/app/assets/javascripts/application.js
199
+ - test/dummy/app/assets/stylesheets/application.css
200
+ - test/dummy/app/assets/config/manifest.js
180
201
  - test/dummy/app/controllers/application_controller.rb
181
- - test/dummy/app/helpers/application_helper.rb
182
- - test/dummy/db/schema.rb
183
- - test/dummy/db/migrate/20160325214849_create_products.rb
184
- - test/dummy/db/migrate/20160325220006_create_category_items.rb
185
- - test/dummy/db/migrate/20160325214744_create_categories.rb
186
- - test/dummy/db/migrate/20160326174530_create_stores.rb
187
- - test/dummy/public/404.html
188
- - test/dummy/public/favicon.ico
189
- - test/dummy/public/500.html
190
- - test/dummy/public/422.html
191
- - test/dummy/config.ru
192
- - test/dummy/Rakefile
193
- - test/dummy/README.rdoc
194
- - test/thermos_test.rb
202
+ - test/dummy/bin/setup
203
+ - test/dummy/bin/bundle
204
+ - test/dummy/bin/rake
205
+ - test/dummy/bin/rails
195
206
  - test/test_helper.rb