Skip to content

Commit

Permalink
Allow filtering. (#30)
Browse files Browse the repository at this point in the history
Allow for logic to govern whether a beverage gets refilled. Can be
useful for saving execution cost and cache space when a model is
unlikely to be queried.

This can be useful when utilizing a cache store that has an eviction
policy, to prevent legacy records that happen to have been updated from
causing a more relevant record to be evicted.
  • Loading branch information
athal7 committed Dec 7, 2020
1 parent c49d83a commit 8e948b3
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 15 deletions.
8 changes: 4 additions & 4 deletions lib/thermos.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
require 'thermos/rebuild_cache_job'

module Thermos
def self.keep_warm(key:, model:, id:, deps: [], lookup_key: nil, &block)
fill(key: key, model: model, deps: deps, lookup_key: lookup_key, &block)
def self.keep_warm(key:, model:, id:, deps: [], lookup_key: nil, filter: nil, &block)
fill(key: key, model: model, deps: deps, lookup_key: lookup_key, filter: filter, &block)
drink(key: key, id: id)
end

def self.fill(key:, model:, deps: [], lookup_key: nil, &block)
def self.fill(key:, model:, deps: [], lookup_key: nil, filter: nil, &block)
BeverageStorage.instance.add_beverage(
Beverage.new(key: key, model: model, deps: deps, action: block, lookup_key: lookup_key)
Beverage.new(key: key, model: model, deps: deps, action: block, lookup_key: lookup_key, filter: filter)
)
end

Expand Down
9 changes: 7 additions & 2 deletions lib/thermos/beverage.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

module Thermos
class Beverage
attr_reader :key, :model, :deps, :action, :lookup_key
attr_reader :key, :model, :deps, :action, :lookup_key, :filter

def initialize(key:, model:, deps:, action:, lookup_key: nil)
def initialize(key:, model:, deps:, action:, lookup_key: nil, filter: nil)
@key = key
@model = model
@lookup_key = lookup_key || :id
@filter = filter || nil
@deps = deps.map do |dep|
Dependency.new(model: model, association: dep)
end
Expand All @@ -25,6 +26,10 @@ def lookup_keys_for_dep_model(dep_model)
end.uniq
end

def should_fill?(model)
@filter.class == Proc ? !!@filter.call(model) : true
end

private

def set_observers
Expand Down
8 changes: 5 additions & 3 deletions lib/thermos/refill_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,18 @@ def perform(model)

def refill_primary_caches(model)
BeverageStorage.instance.beverages.each do |beverage|
if beverage.model == model.class
if beverage.model == model.class && beverage.should_fill?(model)
Thermos::RebuildCacheJob.perform_later(beverage.key, model.send(beverage.lookup_key))
end
end
end

def refill_dependency_caches(model)
BeverageStorage.instance.beverages.each do |beverage|
beverage.lookup_keys_for_dep_model(model).each do |lookup_key|
Thermos::RebuildCacheJob.perform_later(beverage.key, lookup_key)
if beverage.should_fill?(model)
beverage.lookup_keys_for_dep_model(model).each do |lookup_key|
Thermos::RebuildCacheJob.perform_later(beverage.key, lookup_key)
end
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/thermos/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module Thermos
VERSION = '0.3.0'
VERSION = '0.4.0'
end
10 changes: 5 additions & 5 deletions test/dummy/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# Note that this schema.rb definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
# This file is the source Rails uses to define your schema when running `rails
# db:schema:load`. When creating a new database, `rails db:schema:load` tends to
# be faster and is potentially less error prone than running all of your
# migrations from scratch. Old migrations may fail to apply correctly if those
# migrations use external dependencies or application code.
#
# It's strongly recommended that you check this file into your version control system.

Expand Down
17 changes: 17 additions & 0 deletions test/thermos_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,23 @@ def teardown
assert_equal 1, Thermos.drink(key: "key", id: "foo")
assert_raises(MockExpectationError) { mock.verify }
end

test "allows filtering for which records should be rebuilt" do
mock = Minitest::Mock.new
category = categories(:baseball)
filter = ->(model) { model.name.match("ball") }
Thermos.fill(key: "key", model: Category, lookup_key: "name", filter: filter) do |name|
mock.call(name)
end

mock.expect(:call, 1, ["basketball"])
category.update!(name: "basketball")
mock.verify

mock.expect(:call, 1, ["hockey"])
category.update!(name: "hockey")
assert_raises(MockExpectationError) { mock.verify }
end

# has_many model changes
test "rebuilds the cache on has_many model change" do
Expand Down

0 comments on commit 8e948b3

Please sign in to comment.