class InventoryRefresh::SaveCollection::Sweeper
Attributes
inventory_collection[R]
model_class[R]
primary_key[R]
refresh_state[R]
sweep_scope[R]
Public Class Methods
build_scope_set(sweep_scope)
click to toggle source
# File lib/inventory_refresh/save_collection/sweeper.rb, line 37 def build_scope_set(sweep_scope) return [] unless sweep_scope if sweep_scope.kind_of?(Array) sweep_scope.map(&:to_sym).to_set elsif sweep_scope.kind_of?(Hash) sweep_scope.keys.map(&:to_sym).to_set end end
in_scope?(inventory_collection, scope_set)
click to toggle source
# File lib/inventory_refresh/save_collection/sweeper.rb, line 33 def in_scope?(inventory_collection, scope_set) scope_set.include?(inventory_collection&.name) end
new(inventory_collection, refresh_state, sweep_scope)
click to toggle source
# File lib/inventory_refresh/save_collection/sweeper.rb, line 56 def initialize(inventory_collection, refresh_state, sweep_scope) @inventory_collection = inventory_collection @refresh_state = refresh_state @sweep_scope = sweep_scope @model_class = inventory_collection.model_class @primary_key = @model_class.primary_key end
sweep(_ems, inventory_collections, sweep_scope, refresh_state)
click to toggle source
Sweeps inactive records based on :last_seen_on and :refresh_start timestamps. All records having :last_seen_on lower than :refresh_start or nil will be archived/deleted.
@param _ems [ActiveRecord] Manager owning the inventory_collections @param inventory_collections [Array<InventoryRefresh::InventoryCollection>] Array of InventoryCollection
objects
for sweeping
@param sweep_scope
[Array<String, Symbol, Hash>] Array of inventory collection names marking sweep. Or for
targeted sweeping it's array of hashes, where key is inventory collection name pointing to an array of identifiers of inventory objects we want to target for sweeping.
@param refresh_state
[ActiveRecord] Record of :refresh_states
# File lib/inventory_refresh/save_collection/sweeper.rb, line 19 def sweep(_ems, inventory_collections, sweep_scope, refresh_state) scope_set = build_scope_set(sweep_scope) inventory_collections.each do |inventory_collection| next unless sweep_possible?(inventory_collection, scope_set) new(inventory_collection, refresh_state, sweep_scope).sweep end end
sweep_possible?(inventory_collection, scope_set)
click to toggle source
# File lib/inventory_refresh/save_collection/sweeper.rb, line 29 def sweep_possible?(inventory_collection, scope_set) inventory_collection.supports_column?(:last_seen_at) && in_scope?(inventory_collection, scope_set) end
Public Instance Methods
apply_targeted_sweep_scope(all_entities_query)
click to toggle source
# File lib/inventory_refresh/save_collection/sweeper.rb, line 66 def apply_targeted_sweep_scope(all_entities_query) if sweep_scope.kind_of?(Hash) scope = sweep_scope[inventory_collection.name] return all_entities_query if scope.nil? || scope.empty? # Scan the scope to find all references, so we can load them from DB in batches scan_sweep_scope!(scope) scope_keys = Set.new conditions = scope.map { |x| InventoryRefresh::InventoryObject.attributes_with_keys(x, inventory_collection, scope_keys) } assert_conditions!(conditions, scope_keys) all_entities_query.where(inventory_collection.build_multi_selection_condition(conditions, scope_keys)) else all_entities_query end end
assert_conditions!(conditions, scope_keys)
click to toggle source
# File lib/inventory_refresh/save_collection/sweeper.rb, line 99 def assert_conditions!(conditions, scope_keys) conditions.each do |cond| assert_uniform_keys!(cond, scope_keys) assert_non_existent_keys!(cond) end end
assert_non_existent_keys!(cond)
click to toggle source
# File lib/inventory_refresh/save_collection/sweeper.rb, line 115 def assert_non_existent_keys!(cond) return if (diff = (cond.keys.to_set - inventory_collection.all_column_names)).empty? raise(InventoryRefresh::Exception::SweeperNonExistentScopeKeyFoundError, "Sweeping scope for #{inventory_collection} contained keys that are not columns: #{diff.to_a}") end
assert_uniform_keys!(cond, scope_keys)
click to toggle source
# File lib/inventory_refresh/save_collection/sweeper.rb, line 106 def assert_uniform_keys!(cond, scope_keys) return if (diff = (scope_keys - cond.keys.to_set)).empty? raise(InventoryRefresh::Exception::SweeperNonUniformScopeKeyFoundError, "Sweeping scope for #{inventory_collection} contained non uniform keys. All keys for the"\ "scope must be the same, it's possible to send multiple sweeps with different key set. Missing keys"\ " for a scope were: #{diff.to_a}") end
loadable?(value)
click to toggle source
# File lib/inventory_refresh/save_collection/sweeper.rb, line 84 def loadable?(value) inventory_object_lazy?(value) || inventory_object?(value) end
scan_sweep_scope!(scope)
click to toggle source
# File lib/inventory_refresh/save_collection/sweeper.rb, line 88 def scan_sweep_scope!(scope) scope.each do |sc| sc.each_value do |value| next unless loadable?(value) value_inventory_collection = value.inventory_collection value_inventory_collection.add_reference(value.reference, :key => value.key) end end end
sweep()
click to toggle source
# File lib/inventory_refresh/save_collection/sweeper.rb, line 122 def sweep refresh_start = refresh_state.created_at raise "Couldn't load :created_at out of RefreshState record: #{refresh_state}" unless refresh_start table = model_class.arel_table date_field = table[:last_seen_at] all_entities_query = inventory_collection.full_collection_for_comparison all_entities_query = all_entities_query.active if inventory_collection.retention_strategy == :archive && inventory_collection.supports_column?(:archived_at) all_entities_query = apply_targeted_sweep_scope(all_entities_query) query = all_entities_query .where(date_field.lt(refresh_start)).or(all_entities_query.where(:last_seen_at => nil)) .select(table[:id]) query.find_in_batches do |batch| destroy_records!(batch) end end