Skip to content

Instantly share code, notes, and snippets.

@brandonc
Created February 18, 2016 23:05
Show Gist options
  • Save brandonc/8b91a6874dc4e6256c18 to your computer and use it in GitHub Desktop.
Save brandonc/8b91a6874dc4e6256c18 to your computer and use it in GitHub Desktop.
Attach batch progress tracking to a model via concern
module BatchJobStateful
extend ActiveSupport::Concern
included do
field :current_batch_id, type: String
field :last_batch_total, type: Integer
field :last_batch_failures, type: Integer
field :last_batch_created_at, type: Time
field :last_batch_completed_at, type: Time
end
def last_batch_duration
(last_batch_completed_at || 0) - (last_batch_created_at || 0)
end
def last_batch_successful?
(last_batch_total || 0) > 0 && last_batch_failures == 0
end
def processing?
current_batch_status.present? && !current_batch_status.completed?
end
def progress
return nil unless current_batch_status
(current_batch_status.pending - current_batch_status.total).to_f / current_batch_status.total * 100
end
def estimated_completion(throughput_estimate_per_minute)
return nil unless batch
if progress < 0.25
bad_estimated_completion(throughput_estimate_per_minute)
else
good_estimated_completion
end
end
private
def current_batch_status
return @_current_batch_status if defined?(@_current_batch_status)
@_current_batch_status = current_batch_id && Sidekiq::Batch::Status.new(current_batch_id)
end
def bad_estimated_completion(throughput_estimate_per_minute)
now = Time.now
remaining_time = (current_batch_status.total.to_f / throughput_estimate_per_minute).minutes
estimate = current_batch_status.created_at + remaining_time
if estimate > now
estimate
else
now + remaining_time
end
end
def good_estimated_completion
now = Time.now
elapsed_time = now - current_batch_status.created_at
remaining_time = (100 - progress) * elapsed_time
now + remaining_time
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment