lib/eco/api/session/batch_job.rb in eco-helpers-0.6.17 vs lib/eco/api/session/batch_job.rb in eco-helpers-0.7.1
- old
+ new
@@ -1,30 +1,42 @@
module Eco
module API
class Session
class BatchJob < API::Common::Session::BaseSession
- TYPES = [:create, :update, :delete, :get]
+ TYPES = [:get, :create, :update, :delete]
SETS = [:core, :details, :account]
attr_reader :name, :status
+ class << self
+ def valid_type?(value)
+ TYPES.include?(value)
+ end
+
+ def valid_sets?(value)
+ sets = [value].flatten
+ sets.all? { |s| SETS.include?(s) }
+ end
+ end
+
def initialize(e, name:, type:, sets:)
raise "A name is required to refer a job. Given: #{name}" if !name
- raise "Type should be one of #{TYPES}. Given: #{type}" if !BatchJob.valid_type?(type)
- raise "Sets should be some of #{SETS}. Given: #{sets}" if !BatchJob.valid_sets?(sets)
+ raise "Type should be one of #{TYPES}. Given: #{type}" if !self.class.valid_type?(type)
+ raise "Sets should be some of #{SETS}. Given: #{sets}" if !self.class.valid_sets?(sets)
super(e)
@name = name
@type = type
@sets = [sets].flatten.compact
reset
end
def reset
- @queue = []
- @callbacks = {}
- @status = nil
+ @queue = []
+ @queue_hash = {}
+ @callbacks = {}
+ @status = nil
end
def signature
"job \"#{@name}\" ['#{@type.to_s.upcase}': #{sets_title}]"
end
@@ -36,96 +48,144 @@
def pending?
@queue.length > 0
end
- def add(entry)
+ def core?
+ sets.include?(:core)
+ end
+
+ def details?
+ sets.include?(:details)
+ end
+
+ def account?
+ sets.include?(:account)
+ end
+
+ # Adds an entry to the job queue.
+ # @param entry [Person] the person 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.
+ # @return [Void]
+ def add(entry, unique: true)
unless !entry
- @queue.push(entry)
- @callbacks[entry] = Proc.new if block_given?
+ unless unique && @queue_hash.key?(entry)
+ @queue_hash[entry] = true
+ @queue.push(entry)
+ @callbacks[entry] = Proc.new if block_given?
+ end
end
end
- def people
- Eco::API::Organization::People.new(@queue)
+ def people(input = @queue)
+ Eco::API::Organization::People.new(input)
end
def processed_queue
- @queue.map do |entry|
- callback = @callbacks[entry]
- e = entry
- e = callback.call(entry) if callback
- e = nil if as_update(e).empty? && @type!=:delete
+ pre_queue = @queue.map do |e|
+ if callback = @callbacks[e]
+ callback.call(e)
+ end
+ e = nil if as_update(e).empty?
e
end.compact
+ apply_policies(pre_queue)
end
+ def processed_queue
+ @queue.each {|e| @callbacks[e].call(e) if @callbacks.key?(e) }
+ apply_policies(@queue).select {|e| !as_update(e).empty?}
+ end
+
def launch(simulate: false)
queue = processed_queue
launch_feedback(queue, simulate ? 2500 : 800)
- if !simulate && queue.length > 0
- backup_update(queue)
- @status = session.batch.launch(queue, method: @type.to_s)
- @status.root = self
+ if !simulate
+ if queue.length > 0
+ backup_update(queue)
+ @status = session.batch.launch(queue, method: @type)
+ @status.root = self
+ end
end
- logger.info("Simulate: this would have launched: '#{@type.to_s}'") if simulate
+ post_launch(queue: queue, simulate: simulate)
+
+ logger.info("Simulate: this would have launched: '#{@type}'") if simulate
return @status
end
- def core?
- sets.include?(:core)
- end
- def details?
- sets.include?(:dettails)
- end
+ private
- def account?
- sets.include?(:account)
+ def post_launch(queue: [], simulate: false)
+ if !simulate && @status
+ @status.queue.map do |entry|
+ if @status.success?(entry)
+ entry.consolidate! if entry.respond_to?(:consolidate!)
+ #else # shouldn't probably reset, as the model remains dirty? (well tracaked)
+ # entry.reset! if entry.respond_to?(:reset!)
+ end
+ end
+ elsif simulate
+ queue.map do |entry|
+ entry.consolidate! if entry.respond_to?(:consolidate!)
+ end
+ end
end
- def self.valid_type?(value)
- TYPES.include?(value)
+ def apply_policies(pre_queue)
+ pre_queue.tap do |entries|
+ policies = session.config.api_policies.policies
+ unless policies.empty?
+ policies.launch(people: people(entries), session: session)
+ end
+ end
end
- def self.valid_sets?(value)
- sets = [value].flatten
- sets.all? { |s| SETS.include?(s) }
- end
-
- private
-
- def as_update(update)
- hash = update if update.is_a?(Hash)
- if @type == :delete
- hash = update.as_json.slice("id", "external_id")
+ def as_update(entry)
+ hash = entry if entry.is_a?(Hash)
+ if only_ids?
+ hash = entry.as_json.slice("id", "external_id", "email")
else
- hash = update.as_update if update.is_a?(Ecoportal::API::V1::Person)
+ if entry.is_a?(Ecoportal::API::V1::Person)
+ hash = entry.as_update
+ if hfields = hash.dig("details", "fields")
+ hash["details"]["fields"] = hfields.map do |fld|
+ fld.merge!("alt_id" => entry.details.get_field(fld["id"]).alt_id) if entry.details
+ end
+ end
+ end
+
fields = hash&.dig('details', 'fields')
fields&.map! { |fld| fld&.slice("id", "alt_id", "value") }
end
hash || {}
end
+ def only_ids?
+ [:delete, :get].include?(@type)
+ end
+
def sets_title
"#{@sets.map {|s| s.to_s}.join(", ")}"
end
def launch_feedback(data, max_chars = 800)
- if !data || !data.is_a?(Array) || data.empty?
+ if !data || !data.is_a?(Enumerable) || data.empty?
logger.warn("#{"*" * 20} Nothing for #{signature} so far :) #{"*" * 20}")
return
end
header = ("*" * 20) + " #{signature} - Feedback Sample " + ("*" * 20)
logger.info(header)
sample_length = 1
sample = data.slice(0, 20).map do |entry|
- update = as_update(entry)
- max_chars -= update.pretty_inspect.length
+ update = as_update(entry)
+ max_chars -= update.pretty_inspect.length
sample_length += 1 if max_chars > 0
update
end
logger.info("#{sample.slice(0, sample_length).pretty_inspect}")
@@ -133,11 +193,11 @@
logger.info("*" * header.length)
end
def backup_update(data)
data_body = data.map { |u| as_update(u) }
- dir = config.people.requests_folder
- file = File.join(dir, "#{@type.to_s}_data.json")
+ dir = config.people.requests_folder
+ file = File.join(dir, "#{@type}_data.json")
file_manager.save_json(data_body, file, :timestamp)
end
end