Add products cache integrity checker

This commit is contained in:
Rohan Mitchell
2016-02-05 15:16:12 +11:00
parent 687fb6f0aa
commit 1b62dd06b8
6 changed files with 87 additions and 0 deletions

View File

@@ -55,6 +55,7 @@ gem 'figaro'
gem 'blockenspiel'
gem 'acts-as-taggable-on', '~> 3.4'
gem 'paper_trail', '~> 3.0.8'
gem 'diffy'
gem 'wicked_pdf'
gem 'wkhtmltopdf-binary'

View File

@@ -248,6 +248,7 @@ GEM
devise-encryptable (0.1.2)
devise (>= 2.1.0)
diff-lcs (1.2.4)
diffy (3.1.0)
em-websocket (0.5.0)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0.5.3)
@@ -668,6 +669,7 @@ DEPENDENCIES
debugger-linecache
deface!
delayed_job_active_record
diffy
factory_girl_rails
figaro
foreigner

View File

@@ -0,0 +1,38 @@
require 'open_food_network/products_renderer'
ProductsCacheIntegrityCheckerJob = Struct.new(:distributor_id, :order_cycle_id) do
def perform
if diff.any?
Bugsnag.notify RuntimeError.new("Products JSON differs from cached version"), diff: diff.to_s(:color)
end
end
private
def diff
@diff ||= Diffy::Diff.new pretty(cached_json), pretty(rendered_json)
end
def pretty(json)
JSON.pretty_generate JSON.parse json
end
def cached_json
Rails.cache.read("products-json-#{distributor_id}-#{order_cycle_id}") || {}.to_json
end
def rendered_json
OpenFoodNetwork::ProductsRenderer.new(distributor, order_cycle).products_json
rescue OpenFoodNetwork::ProductsRenderer::NoProducts
nil
end
def distributor
Enterprise.find distributor_id
end
def order_cycle
OrderCycle.find order_cycle_id
end
end

View File

@@ -7,6 +7,10 @@ env "MAILTO", "rohan@rohanmitchell.com"
# If we use -e with a file containing specs, rspec interprets it and filters out our examples
job_type :run_file, "cd :path; :environment_variable=:environment bundle exec script/rails runner :task :output"
every 1.hour do
rake 'openfoodnetwork:cache:check_products_cache_integrity'
end
every 1.day, at: '12:05am' do
run_file "lib/open_food_network/integrity_checker.rb"
end

16
lib/tasks/cache.rake Normal file
View File

@@ -0,0 +1,16 @@
namespace :openfoodnetwork do
namespace :cache do
desc 'check the integrity of the products cache'
task :check_products_cache_integrity => :environment do
exchanges = Exchange.
outgoing.
joins(:order_cycle).
merge(OrderCycle.dated).
merge(OrderCycle.not_closed)
exchanges.each do |exchange|
Delayed::Job.enqueue ProductsCacheIntegrityCheckerJob.new(exchange.receiver, exchange.order_cycle), priority: 20
end
end
end
end

View File

@@ -0,0 +1,26 @@
require 'spec_helper'
require 'open_food_network/products_renderer'
describe ProductsCacheIntegrityCheckerJob do
describe "reporting on differences between the products cache and the current products" do
let(:distributor) { create(:distributor_enterprise) }
let(:order_cycle) { create(:simple_order_cycle) }
let(:job) { ProductsCacheIntegrityCheckerJob.new distributor.id, order_cycle.id }
before do
Rails.cache.write "products-json-#{distributor.id}-#{order_cycle.id}", "[1, 2, 3]\n"
OpenFoodNetwork::ProductsRenderer.stub(:new) { double(:pr, products_json: "[1, 3]\n") }
end
it "reports errors" do
expect(Bugsnag).to receive(:notify)
run_job job
end
it "deals with nil cached_json" do
Rails.cache.clear
expect(Bugsnag).to receive(:notify)
run_job job
end
end
end