require_relative 'awaiter/timer' require_relative 'awaiter/status_frequency' module Ecoportal module API class V1 class Job class Awaiter include Common::Client::TimeOut include StatusFrequency TIMEOUT_APPROACH = :min # :conservative # adaptative timeout TIMEOUT_FALLBACK = :min attr_reader :job_api, :job_id, :total def initialize(job_api, job_id:, total:) @job_api = job_api @job_id = job_id @total = total end attr_writer :timeout_approach def timeout_approach @timeout_approach ||= self.class::TIMEOUT_APPROACH end # Allows to preserve the learned throughput def new(**kargs) self.class.new(job_api, **kargs).tap do |out| out.throughput = throughput out.timeout_approach = timeout_approach end end def await_completion! # rubocop:disable Metrics/AbcSize timeout = timeout_for(total, approach: timeout_approach) first = 1 timer = Timer.new( total: total, timeout: timeout, ldelay: first ) delay_status_check = nil loop do sleep(first.tap {first = nil}) if first timer = timer.new( status: job_api.status(job_id), ldelay: delay_status_check ) # ratio = throughput!(timer.net_waited, count: timer.progress) ratio = throughput!(timer.lwaited, count: timer.increased) break timer.status if timer.complete? timer.on_timeout! do @timeout_approach = self.class::TIMEOUT_FALLBACK end delay_status_check = status_check_in( timer.pending, timeout_in: timer.timeout_in ) msg = " ... Awaiting #{delay_status_check} s. -- " msg << " TimeOut: #{timer.time_left} s. " msg << "(job '#{job_id}') " msg << "Done: #{timer.progress} (est. #{ratio.round(2)} rec/s) " msg << " \r" print msg $stdout.flush sleep(delay_status_check) end end end end end end end