Project

General

Profile

« Previous | Next » 

Revision a152a1b2

Added by Tomer Brisker over 8 years ago

Fixes #11444 - Correctly count hosts in domain

Only hosts that have a primary nic assigned to a domain should be
counted in the domain host count. Previous implementation was flawed in
that it only updated the counter in certain occasions and not all,
leading sometimes to incorrect host counts.
I have implemented the counter updates in `after_commit` to reduce
chance of deadlocks.

View differences:

app/models/nic/base.rb
scope :provision, -> { where(:provision => true) }
belongs_to :subnet
belongs_to :domain, :counter_cache => 'hosts_count'
belongs_to :domain
belongs_to_host :inverse_of => :interfaces, :class_name => "Host::Base"
# do counter cache only for primary interfaces
def belongs_to_counter_cache_after_create_for_domain
super if self.primary
end
def belongs_to_counter_cache_before_destroy_for_domain
super if self.primary
end
# We only want to update the counters for primary interfaces, don't use cached_counter
after_commit :update_domain_counters_on_create, :on => :create
after_commit :update_domain_counters_on_update, :on => :update
after_commit :update_domain_counters_on_destroy, :on => :destroy
# keep extra attributes needed for sub classes.
serialize :attrs, Hash
......
interface_attribute_uniqueness(:mac, Nic::Base.physical.is_managed)
end
def update_domain_counters_on_create
return unless primary? && domain_id.present?
domain.increment!('total_hosts')
end
def update_domain_counters_on_update
primary_changed = previous_changes.include? 'primary'
domain_changed = previous_changes.include? 'domain_id'
if primary_changed
if primary? #changed from non-primary to primary
domain.increment!('total_hosts') if domain_id.present?
else #changed from primary to non-primary
if domain_changed
Domain.unscoped.find(previous_changes['domain_id'][0]).decrement!('total_hosts') if previous_changes['domain_id'][0].present?
else
domain.decrement!('total_hosts') if domain_id.present?
end
end
elsif domain_changed && primary?
Domain.unscoped.find(previous_changes['domain_id'][0]).decrement!('total_hosts') if previous_changes['domain_id'][0].present?
domain.increment!('total_hosts') if domain_id.present?
end
end
def update_domain_counters_on_destroy
return unless primary? && domain_id.present?
domain.decrement!('total_hosts')
end
private
def interface_attribute_uniqueness(attr, base = Nic::Base.where(nil))

Also available in: Unified diff