Skip to content

Commit 5bac218

Browse files
jefftmarksbinq
andauthored
Edm 653/lcpe cache logic (#1314)
* preload dataset * update to sql context * Create preload dataset and implement logic * Migrations * Revert migrations * schema * Update sample program file with ojt_app_type column * Revert "Update sample program file with ojt_app_type column" This reverts commit 27ed455. * Implement preload datasets * Update enriched id * Refactor * Add period * Remove period * revert Gemfile.lock * linting * Update specs --------- Co-authored-by: Vanson Samuel <[email protected]>
1 parent 3e7d40b commit 5bac218

File tree

19 files changed

+171
-49
lines changed

19 files changed

+171
-49
lines changed

app/controllers/v1/lcpe/exams_controller.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
# frozen_string_literal: true
22

3-
class V1::Lcpe::ExamsController < ApiController
3+
class V1::Lcpe::ExamsController < V1::LcpeBaseController
4+
before_action :validate_preload_version, only: :show
5+
46
def index
5-
results = Lcpe::Exam.with_enriched_id
7+
results = preload_dataset || Lcpe::Exam.with_enriched_id
68

79
render json: results, each_serializer: Lcpe::ExamSerializer, adapter: :json, action: 'index'
810
end

app/controllers/v1/lcpe/lacs_controller.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
# frozen_string_literal: true
22

3-
class V1::Lcpe::LacsController < ApiController
3+
class V1::Lcpe::LacsController < V1::LcpeBaseController
4+
before_action :validate_preload_version, only: :show
5+
46
def index
57
render(
68
{
7-
json: list,
9+
json: preload_dataset || list,
810
each_serializer: Lcpe::LacSerializer,
911
adapter: :json,
1012
action: 'index'
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# frozen_string_literal: true
2+
3+
module V1
4+
class LcpeBaseController < ApiController
5+
class PreloadVersionStaleError < StandardError; end
6+
7+
rescue_from PreloadVersionStaleError, with: :version_invalid
8+
9+
private
10+
11+
def validate_preload_version
12+
preload_version = params[:id].split('@').last
13+
raise PreloadVersionStaleError unless preload_version == fresh_preload.id.to_s
14+
end
15+
16+
def preload_dataset
17+
return if bypass_versioning?
18+
19+
set_etag(fresh_preload.id.to_s)
20+
JSON.parse(fresh_preload.body)
21+
end
22+
23+
def fresh_preload
24+
@fresh_preload ||= ::Lcpe::PreloadDataset.fresh(lcpe_type)
25+
end
26+
27+
def lcpe_type
28+
"Lcpe::#{controller_name.singularize.titleize}"
29+
end
30+
31+
def set_etag(preload_version)
32+
response.set_header('ETag', preload_version)
33+
end
34+
35+
# If additional filter params present, bypass versioning
36+
def bypass_versioning?
37+
scrubbed_params.present?
38+
end
39+
40+
def scrubbed_params
41+
params.except(:format, :controller, :action, controller_name.singularize.to_sym)
42+
end
43+
44+
def version_invalid
45+
render json: { error: 'Version invalid' }, status: :conflict
46+
end
47+
end
48+
end

app/models/lcpe/exam.rb

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,21 @@
22

33
module Lcpe
44
class Exam < ApplicationRecord
5-
REF_CODE_FN = "RIGHT(MD5(CONCAT(facility_code, '-', nexam_nm)), 5)"
6-
75
extend SqlContext
86

97
# using Enriched IDs is a good way to ensure that
108
# a stale ID preloaded from the browser is not used.
119
# :nocov:
1210
scope :with_enriched_id, lambda {
11+
preload_id = Lcpe::PreloadDataset.fresh(klass.to_s).id
1312
select(
1413
'*',
15-
"#{REF_CODE_FN} AS ref_code",
16-
"CONCAT(id, '@', #{REF_CODE_FN}) enriched_id"
14+
"CONCAT(id, '@', #{preload_id}) enriched_id"
1715
)
1816
}
1917

2018
scope :by_enriched_id, lambda { |enriched_id|
21-
id, = enriched_id.match(/\A(\d+)@(.+)\z/).values_at(1, 2)
19+
id = enriched_id.split('@').first
2220

2321
with(enriched_query: with_enriched_id.where('id = ?', id))
2422
.select("#{table_name}.*", 'enriched_query.enriched_id')

app/models/lcpe/feed.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,13 @@ def self.table_name_prefix
99

1010
'lcpe_feed_'
1111
end
12+
13+
# Each Lcpe::Feed:: model should clarify the NORMALIZED_KLASS it's associated with
14+
# For example, Lcpe::Feed::Nexam normalizes to Lcpe::Exam
15+
def self.normalized_klasses
16+
Lcpe::Feed.constants.map do |const|
17+
feed = Lcpe::Feed.const_get(const)
18+
feed.const_get(:NORMALIZED_KLASS) if feed.const_defined?(:NORMALIZED_KLASS)
19+
end.compact
20+
end
1221
end

app/models/lcpe/feed/lac.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ class Lac < ImportableRecord
1313
'lc_test_fee' => { column: :fee_amt, converter: Converters::BaseConverter }
1414
}.freeze
1515

16+
NORMALIZED_KLASS = 'Lcpe::Lac'
17+
1618
def self.normalize
1719
pure_sql
1820
.join(Lcpe::Lac.reset)

app/models/lcpe/feed/nexam.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ class Nexam < ImportableRecord
1414
'nexam_fee_to_date' => { column: :end_dt, converter: Converters::BaseConverter }
1515
}.freeze
1616

17+
NORMALIZED_KLASS = 'Lcpe::Exam'
18+
1719
def self.normalize
1820
pure_sql
1921
.join(Lcpe::Exam.reset)

app/models/lcpe/lac.rb

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,21 @@
22

33
module Lcpe
44
class Lac < ApplicationRecord
5-
REF_CODE_FN = "RIGHT(MD5(CONCAT(facility_code, '-', lac_nm)), 5)"
6-
75
extend SqlContext
86

97
# using Enriched IDs is a good way to ensure that
108
# a stale ID preloaded from the browser is not used.
119
# :nocov:
1210
scope :with_enriched_id, lambda {
11+
preload_id = Lcpe::PreloadDataset.fresh(klass.to_s).id
1312
select(
1413
'*',
15-
"#{REF_CODE_FN} AS ref_code",
16-
"CONCAT(id, '@', #{REF_CODE_FN}) enriched_id"
14+
"CONCAT(id, '@', #{preload_id}) enriched_id"
1715
)
1816
}
1917

2018
scope :by_enriched_id, lambda { |enriched_id|
21-
id, = enriched_id.match(/\A(\d+)@(.+)\z/).values_at(1, 2)
19+
id = enriched_id.split('@').first
2220

2321
with(enriched_query: with_enriched_id.where('id = ?', id))
2422
.select("#{table_name}.*", 'enriched_query.enriched_id')

app/models/lcpe/preload_dataset.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# frozen_string_literal: true
2+
3+
class Lcpe::PreloadDataset < ApplicationRecord
4+
# ['Lcpe::Lac', 'Lcpe::Exam']
5+
LCPE_TYPES = Lcpe::Feed.normalized_klasses.freeze
6+
7+
validates :subject_class, presence: true, inclusion: { in: LCPE_TYPES }
8+
9+
scope :of_type, ->(lcpe_type) { where(subject_class: lcpe_type).order(created_at: :desc) }
10+
scope :stale, ->(lcpe_type) { of_type(lcpe_type).offset(1) }
11+
12+
def self.fresh(lcpe_type)
13+
of_type(lcpe_type).first
14+
end
15+
16+
def self.build(lcpe_type)
17+
# wipe all exepct most recent preload for lcpe type
18+
stale(lcpe_type).destroy_all
19+
create(subject_class: lcpe_type).tap do |preload|
20+
dataset = preload.klass.with_enriched_id
21+
preload.update(body: dataset.to_json)
22+
end
23+
end
24+
25+
def klass
26+
subject_class.constantize
27+
end
28+
end

app/models/upload.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ def normalize_lcpe!
128128
subject = csv_type&.constantize
129129

130130
subject.normalize.execute
131+
str_klass = subject.const_get(:NORMALIZED_KLASS)
132+
Lcpe::PreloadDataset.build(str_klass)
131133
rescue StandardError
132134
nil
133135
end

0 commit comments

Comments
 (0)