lib/eco/api/session/batch.rb in eco-helpers-2.0.42 vs lib/eco/api/session/batch.rb in eco-helpers-2.0.43
- old
+ new
@@ -90,46 +90,83 @@
fatal "cannot batch get without api connnection, please provide a valid api connection!" unless people_api = api&.people
params = {per_page: DEFAULT_BATCH_BLOCK}.merge(params)
return people_api.get_all(params: params, silent: silent)
end
+
def batch_from(data, method:, params: {}, silent: false)
fatal "Invalid batch method: #{method}." if !self.class.valid_method?(method)
return nil if !data || !data.is_a?(Enumerable)
fatal "cannot batch #{method} without api connnection, please provide a valid api connection!" unless people_api = api&.people
# param q does not make sense here, even for GET method
params = {per_page: DEFAULT_BATCH_BLOCK}.merge(params)
per_page = params[:per_page] || DEFAULT_BATCH_BLOCK
+ launch_batch(data,
+ method: method,
+ per_page: per_page,
+ people_api: people_api,
+ silent: silent
+ )
+ end
+
+ def launch_batch(data, method:, status: nil, job_mode: true, per_page: DEFAULT_BATCH_BLOCK, people_api: api&.people, silent: false)
iteration = 1; done = 0
iterations = (data.length.to_f / per_page).ceil
- Eco::API::Session::Batch::Status.new(enviro, queue: data, method: method).tap do |status|
+ status ||= Eco::API::Session::Batch::Status.new(enviro, queue: data, method: method)
+ status.tap do |status|
start_time = Time.now
start_slice = Time.now; slice = []
+ pending_for_server_error = data.to_a[0..-1]
data.each_slice(per_page) do |slice|
msg = "starting batch '#{method}' iteration #{iteration}/#{iterations},"
msg += " with #{slice.length} entries of #{data.length} -- #{done} done"
msg += " (last: #{str_stats(start_slice, slice.length)}; total: #{str_stats(start_time, done)})"
logger.info(msg) unless silent
start_slice = Time.now
offer_retry_on(Ecoportal::API::Errors::TimeOut) do
- people_api.batch do |batch|
+ people_api.batch(job_mode: false) do |batch|
slice.each do |person|
batch.public_send(method, person) do |response|
faltal("Request with no response") unless !!response
- status[person] = response
+ unless server_error?(response)
+ pending_for_server_error.delete(person)
+ status[person] = response
+ end
end
end
end # end batch
end
iteration += 1
done += slice.length
end # next slice
+
+ # temporary working around (due to back-end problems with batch/jobs)
+ unless pending_for_server_error.empty?
+ msg = "Going to re-try #{pending_for_server_error.count} due to server errors"
+ logger.info(msg) unless silent
+ launch_batch(pending_for_server_error,
+ status: status,
+ method: method,
+ job_mode: false,
+ per_page: per_page,
+ people_api: people_api,
+ silent: silent
+ )
+ end
end
+ end
+
+ def server_error?(response)
+ res_status = response.status
+ server_error = !res_status || res_status.server_error?
+ other_error = !server_error && (!res_status.code || res_status.code < 100)
+ no_body = !server_error && !other_error && !response.body
+ server_error || other_error || no_body
end
def offer_retry_on(error_type, retries_left = 3, &block)
begin
block.call