-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathschedule.rb
executable file
·70 lines (59 loc) · 2.26 KB
/
schedule.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# Object to look at the DB to determine if work needs to be done and schedule
# that work to accomplish it.
module Solidus::ElasticProduct
class Schedule
BATCH_SIZE = 500
CHECK_EVERY = 1.minute
class << self
# Enters into an infinate loop where we monitor the DB looking for work that
# needs to be done and fires off workers to handle that work.
#
# Designed to be executed as a deamon so if SIGTERM is sent to the process
# it will finish the current loop then exit cleanly.
def monitor
should_exit = false
trap('TERM') { should_exit = true }
until should_exit do
new.check_and_schedule
sleep CHECK_EVERY
end
end
# Prior to running the initialization job if we have a lot of unserialized
# product, you can run this method to schedule getting it serialized.
def serialize_all
new.serialize_all
end
end
# Checks the DB for work and schedules it if necessary
def check_and_schedule
return unless Config.incremental_update_enabled
Rails.logger.info "Checking for work"
serialize
upload
end
def serialize_all # :nodoc:
serialize State.all
end
private
# If records need to be serialized kick off workers to handle them in batches.
def serialize scope = State.needing_serialization
assign_to job: :serializer, lock: :locked_for_serialization_at, scope: scope
end
# If records need to be uploaded kick off workers to handle them in batches
def upload
scope = State.needing_upload
assign_to job: :uploader, lock: :locked_for_upload_at, scope: scope
end
# Will actually load the records that need to be batched and assign each
# to a job for a worker to handle.
def assign_to job:, lock:, scope:
Rails.logger.info "Found work for: #{job}"
table = State.table_name
scope.select("#{table}.id, #{table}.product_id").find_in_batches batch_size: BATCH_SIZE do |batch|
product_ids = batch.collect &:product_id
scope.where(product_id: product_ids).update_all lock => Time.current
Solidus::ElasticProduct::const_get("#{job.to_s.camelize}Job").perform_later product_ids unless product_ids.empty?
end
end
end
end