lib/eco/api/session/batch.rb in eco-helpers-3.0.14 vs lib/eco/api/session/batch.rb in eco-helpers-3.0.15

- old
+ new

@@ -1,26 +1,33 @@ module Eco module API class Session class Batch < Common::Session::BaseSession - DEFAULT_BATCH_BLOCK = 50 - VALID_METHODS = %i[get create update upsert delete].freeze + DEFAULT_BATCH_SIZE = 50 + DEFAULT_JOB_SIZE = 100 + VALID_METHODS = %i[get create update upsert delete].freeze class << self # @return [Boolean] `true` if the method is supported, `false` otherwise. def valid_method?(value) VALID_METHODS.include?(value) end end + def batch_size(opts = options) + return self.class::DEFAULT_JOB_SIZE if job_mode?(opts) + + self.class::DEFAULT_BATCH_SIZE + end + # @return [Symbol] the batch mode to run - def batch_mode(opts = self.options) + def batch_mode(opts = options) opts.dig(:workflow, :batch, :mode) || :batch end # @return [Boolean] are we running in `:job` mode? - def job_mode?(opts = self.options) + def job_mode?(opts = options) batch_mode(opts) == :job end # Gets the _people_ of the organization according `params`. # If `people` is not `nil`, scopes to only the people specified. @@ -30,14 +37,20 @@ # @param params [Hash] api request options. # @option params [String] :page the page number `page` based on `:per_page`. # @option params [String] :per_page the number of people included per each batch api request. # @option params [String] :q some text to search. Omit this parameter to target all the people. # @return [Array<People>] all the people based on `params` - def get_people(people = nil, params: {}, silent: false) - return launch(people, method: :get, params: params, silent: silent).people if people.is_a?(Enumerable) + def get_people(people = nil, params: {}, silent: false, options: self.options) + return get(params: params, silent: silent, options: options) unless people.is_a?(Enumerable) - get(params: params, silent: silent) + launch( + people, + method: :get, + params: params, + silent: silent, + options: options + ).people end # launches a batch of `method` type using `people` and the specified `params` # @raise Exception # - if `people` is `nil` or is not an `Enumerable`. @@ -45,18 +58,30 @@ # @param people [People, Enumerable<Person>, Enumerable<Hash>] target _People_ to launch the batch against. # @param method [Symbol] the method to launch the batch api request with. # @param params [Hash] api request options. # @option params [String] :per_page the number of people included per each batch api request. # @return [Batch::Status] the `status` of this batch launch. - def launch(people, method:, params: {}, silent: false) - batch_from(people, method: method, params: params, silent: silent) + def launch(people, method:, params: {}, silent: false, options: self.options) + batch_from( + people, + method: method, + params: params, + silent: silent, + options: options + ) end - def search(data, silent: false, params: {}) # rubocop:disable Metrics/AbcSize - params = {per_page: DEFAULT_BATCH_BLOCK}.merge(params) + def search(data, silent: false, params: {}, options: self.options) # rubocop:disable Metrics/AbcSize + params = {per_page: batch_size(options)}.merge(params) - launch(data, method: :get, params: params, silent: silent).tap do |status| + launch( + data, + method: :get, + params: params, + silent: silent, + options: options + ).tap do |status| status.mode = :search entries = status.queue puts "\n" entries.each_with_index do |entry, i| @@ -76,11 +101,15 @@ end people_matching = [] email = email.to_s.strip.downcase unless email.empty? - people_matching = get(params: params.merge(q: email), silent: silent).select do |person| + people_matching = get( + params: params.merge(q: email), + silent: silent, + options: options + ).select do |person| person.email == email end end case people_matching.length @@ -93,35 +122,42 @@ end end private - def get(params: {}, silent: false) + def get(params: {}, silent: false, options: self.options) msg = "cannot batch get without api connnection, please provide a valid api connection!" fatal msg unless (people_api = api&.people) - params = {per_page: DEFAULT_BATCH_BLOCK}.merge(params) + params = {per_page: batch_size(options)}.merge(params) people_api.get_all(params: params, silent: silent) end - def batch_from(data, method:, params: {}, silent: false) + def batch_from( + data, + method:, + params: {}, + silent: false, + options: self.options + ) fatal "Invalid batch method: #{method}." unless self.class.valid_method?(method) return nil if !data || !data.is_a?(Enumerable) msg = "cannot batch #{method} without api connnection, please provide a valid api connection!" fatal msg 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 + params = {per_page: batch_size(options)}.merge(params) + per_page = params[:per_page] || batch_size(options) launch_batch( data, method: method, per_page: per_page, people_api: people_api, - silent: silent + silent: silent, + options: options ) end # Default way to retrieve options (unless provided) def options @@ -131,14 +167,14 @@ def launch_batch( # rubocop:disable Metrics/AbcSize data, method:, status: nil, job_mode: true, # rubocop:disable Lint/UnusedMethodArgument - per_page: DEFAULT_BATCH_BLOCK, + options: self.options, + per_page: batch_size(options), people_api: api&.people, - silent: false, - options: self.options + silent: false ) iteration = 1 done = 0 iterations = (data.length.to_f / per_page).ceil @@ -189,11 +225,12 @@ status: status, method: method, job_mode: false, per_page: per_page, people_api: people_api, - silent: silent + silent: silent, + options: options ) end end end @@ -204,14 +241,15 @@ 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) - block.call - rescue error_type - raise unless retries_left.positive? + yield + rescue error_type => err + raise err.class, err.message, cause: nil unless retries_left.positive? - explanation = "Batch TimeOut. You have #{retries_left} retries left." + explanation = "#{err}\n" + explanation << "You have #{retries_left} retries left." question = " Do you want to retry (y/N)?" prompt_user(question, default: "Y", explanation: explanation, timeout: 10) do |response| raise unless response.upcase.start_with?("Y")