lib/eco/api/session/batch/job.rb in eco-helpers-1.1.2 vs lib/eco/api/session/batch/job.rb in eco-helpers-1.1.3
- old
+ new
@@ -64,20 +64,10 @@
# @return [Hash] options the root `usecase` is run with
def options
usecase?? usecase.options : {}
end
- def match?(type:, sets:)
- sets = [sets].flatten
- type == self.type && (sets.order == self.sets.order)
- end
-
- # @return [Boolean] has been this `batch job` launched?
- def pending?
- @pending
- end
-
# Adds an entry(ies) to the job queue.
# @param entry [Person, Enumberable<Person>] the person(s) we want to update, carrying the changes to be done.
# @param unique [Boolean] specifies if repeated entries should be avoided in the queue.
# @yield [person] callback before launching the batch job request against the server.
# @yeldparam param [Person] current person object that that should be treated by the callback before launching the batch.
@@ -95,50 +85,114 @@
end
end
end
end
+ #def match?(type:, sets:)
+ # sets = [sets].flatten
+ # type == self.type && (sets.order == self.sets.order)
+ #end
+
+ # @return [Boolean] has been this `batch job` launched?
+ def pending?
+ @pending
+ end
+
+ # @note it requires launch to be firstly invoked
+ # @raise [Exception] if 'launch' has not firstly invoked
+ # @return [Enumbrable<Hash>] the last requests that the queue will generate
+ def requests
+ raise "Method missuse. Firstly 'launch' should be invoked" unless instance_variable_defined?(:@requests)
+ @requests
+ end
+
+ # @see Eco::API::Session::Batch::Feedback#request_stats
+ def request_stats(requests = nil)
+ feedback.request_stats(requests || self.requests)
+ end
+
+ # @see Eco::API::Session::Batch::Status#errors?
+ # @return [Boolean] `true` if there were Server errors, `false` otherwise
+ def errors?
+ status && status.errors?
+ end
+
# Helper/shortcut to obtain a people object out of `input`
# @note if `input` is not provided, it will use `queue`
# @return [Eco::API::Organization::People]
def people(input = @queue)
Eco::API::Organization::People.new(input)
end
# Processes the `queue` and, unless `simulate` is `true`, launches against the server:
- # 1. if the entries of `queue` got pending _callbacks_ (delayed changes), it processes them
- # 2. unless type == `:create`: if there's a defined `api_excluded` _callback_ it calls it (see `Eco::API::Session::Config::People#api_excluded`)
- # 3. transforms the result to a `Eco::API::Organization::People` object
- # 4. if there are `api policies` defined, it passes the entries through them in order (see `Eco::API::Session::Config#policies`)
- # 5. at this point all the transformations have taken place...
- # 6. only include the entries that, after all above, still hold pending changes (`!as_update.empty?`) to be launched as update
- # 7. if we are **not** in `dry-run` (or `simulate`), launch the batch request against the server (see `Eco::API::Session::Batch#launch`)
- # 8. next, it links the resulting batch `status` to this `Batch::Job` (see `Eco::API::Session::Batch::Status`)
- # 9. the post launch kicks in, and for success requests, it consolidates the associated entries (see `Ecoportal::API::V1::Person#consolidate!`)
- # 10. launches specific error handlers, if there were **errors** from the Server as a result of the `batch.launch`, and there are `Error::Handlers` defined
- # 11. if we are **not** in `dry-run` (or `simulate`), it backs up the raw queries launched to the Server
+ # 1. pre_processes the queue obtaining the `requests`:
+ # - if the entries of `queue` got pending _callbacks_ (delayed changes), it processes them
+ # - unless type == `:create`: if there's a defined `api_excluded` _callback_ it calls it (see `Eco::API::Session::Config::People#api_excluded`)
+ # - transforms the result to a `Eco::API::Organization::People` object
+ # - if there are `api policies` defined, it passes the entries through them in order (see `Eco::API::Session::Config#policies`)
+ # - this step is **skipped** if the option `-skip-api-policies` was used in the command line
+ # - at this point all the transformations have taken place...
+ # - only include the entries that, after all above, still hold pending changes (`!as_update.empty?`) to be launched as update
+ # 2. pre launch checks against the `requests`:
+ # - it generates `stats` (`Eco::API::Session::Batch::RequestStats`) out of the requests
+ # - if there is a batch policy declared for the current job `type`, it checks compliance against `stats` (`Eco::API::Session::Batch::Policies`),
+ # - a non-compliant batch will stop the current session by raising an `Exception`
+ # - this setp is **skipped** if the option `-skip-batch-policy` was used in the command line
+ # 3. if we are **not** in `dry-run` (or `simulate`), it:
+ # - backs up the raw queries (`requests`) launched to the Server, if we are **not** in `dry-run` (or `simulate`)
+ # - **launches the batch** request against the _Server_ (see `Eco::API::Session::Batch#launch`)
+ # - links the resulting batch `status` to this `Batch::Job` (see `Eco::API::Session::Batch::Status`)
+ # - prints any `errors` replied by the _Server_
+ # 4. the post launch kicks in, and:
+ # - for success requests, it consolidates the associated entries (see `Ecoportal::API::V1::Person#consolidate!`)
+ # - launches specific error handlers, if there were **errors** from the Server as a result of the `batch.launch`, and there are `Error::Handlers` defined
+ # @return [Eco::API::Session::Batch::Status]
def launch(simulate: false)
- pqueue = processed_queue
- requests = pqueue.map {|e| as_update(e)}
+ pqueue = processed_queue
+ @requests = pqueue.map {|e| as_update(e)}
pre_checks(requests, simulate: simulate)
- if !simulate
+ unless simulate
if pqueue.length > 0
backup_update(requests)
- @status = session.batch.launch(pqueue, method: type)
- @status.root = self
+ session.batch.launch(pqueue, method: type).tap do |job_status|
+ @status = job_status
+ status.root = self
+ status.errors.print
+ end
end
end
- post_launch(queue: pqueue, simulate: simulate)
+ unless requests.empty?
+ logger.info("--- simulate mode (dry-run) -- job '#{name}' -- this would have launched #{type.to_s.upcase}") if simulate
+ end
- logger.info("Simulate: this would have launched: '#{type}'") if simulate
+ post_launch(queue: pqueue, simulate: simulate)
@pending = false
- return @status
+ return status
end
+ # Provides a text summary of the current status
+ # @note if `launch` was not invoked, it specifies so
+ # @return [String] the summary
+ def summary
+ [].tap do |msg|
+ if pending?
+ msg << "PENDING - Batch #{type.to_s.upcase} - job '#{name}' - length: #{@queue.length}"
+ else
+ msg << feedback.generate(requests, only_stats: true)
+ if batch_policy && !batch_policy.compliant?(request_stats)
+ msg << "Batch Policy Uncompliance:"
+ msg << batch_policy.uncompliance(request_stats)
+ end
+
+ msg << status.errors.message unless !status
+ end
+ end.join("\n")
+ end
+
private
def as_update(*args)
feedback.as_update(*args)
end
@@ -176,31 +230,32 @@
only_stats = options.dig(:feedback, :only_stats)
max_chars = simulate ? 2500 : 800
msg = feedback.generate(requests, max_chars: max_chars, only_stats: only_stats)
logger.info(msg)
- @request_stats = feedback.request_stats(requests)
- if simulate && batch_policy && !batch_policy.compliant?(@request_stats)
+ # batch_policy
+ stats = request_stats(requests)
+ if simulate && batch_policy && !batch_policy.compliant?(stats)
logger.warn("Batch Policy Uncompliance: this and next batches will be aborted!")
- logger.warn(batch_policy.uncompliance(@request_stats))
+ logger.warn(batch_policy.uncompliance(stats))
elsif batch_policy
# will throw an Exception if the policy request_stats is not compliant
- batch_policy.validate!(@request_stats)
+ batch_policy.validate!(stats)
end
end
def post_launch(queue: [], simulate: false)
- if !simulate && @status
- @status.queue.map do |entry|
- if @status.success?(entry)
+ if !simulate && status
+ status.queue.map do |entry|
+ if status.success?(entry)
entry.consolidate! if entry.respond_to?(:consolidate!)
#else # do not entry.reset! (keep track on changes still)
end
end
# launch_error handlers
handlers = session.config.error_handlers
- if @status.errors.any? && !handlers.empty?
- err_types = @status.errors.by_type
+ if status.errors.any? && !handlers.empty?
+ err_types = status.errors.by_type
handlers.each do |handler|
if entries = err_types[handler.name]
handler.launch(people: people(entries), session: session, options: options)
end
end