Optimize contact linked status update #2477

This commit is contained in:
Priit Tark 2015-07-23 20:02:01 +03:00
parent 8700beea60
commit 48bc4d4ac9
3 changed files with 48 additions and 19 deletions

View file

@ -260,21 +260,11 @@ class Contact < ActiveRecord::Base
Country.new(country_code)
end
# Find a way to use self.domains with contact
def domains_owned
Domain.where(registrant_id: id)
end
def relations_with_domain?
return true if domain_contacts.present? || domains_owned.present?
false
end
# TODO: refactor, it should not allow to destroy with normal destroy,
# no need separate method
# should use only in transaction
def destroy_and_clean
if relations_with_domain?
if domains_present?
errors.add(:domains, :exist)
return false
end
@ -316,14 +306,34 @@ class Contact < ActiveRecord::Base
end
end
# optimization under children loop,
# otherwise bullet will not be happy
def domains_present?
return @domains_present if @domains_present
domain_contacts.present? || registrant_domains.present?
end
# for overwrite when doing children loop
def domains_present=(boolean)
@domains_present = boolean
end
def manage_linked
if domains.present?
statuses << LINKED if statuses.detect { |s| s == LINKED }.blank?
if domains_present?
set_linked
else
statuses.delete_if { |s| s == LINKED }
unset_linked
end
end
def set_linked
statuses << LINKED if statuses.detect { |s| s == LINKED }.blank?
end
def unset_linked
statuses.delete_if { |s| s == LINKED }
end
# rubocop:disable Metrics/CyclomaticComplexity
def manage_ok
return unset_ok unless valid?

View file

@ -16,10 +16,20 @@ class Epp::Domain < Domain
false
end
before_save :update_contact_status
def update_contact_status
before_save :link_contacts
def link_contacts
# Based on bullet report
unlinked_contacts = contacts.select { |c| !c.linked? } # speed up a bit
unlinked_contacts.each do |uc|
uc.domains_present = true # no need to fetch domains again
uc.save(validate: false)
end
end
after_destroy :unlink_contacts
def unlink_contacts
contacts.each do |c|
next if c.linked?
c.domains_present = false
c.save(validate: false)
end
end

View file

@ -44,18 +44,27 @@ Rails.application.configure do
# The available log levels are: :debug, :info, :warn, :error, :fatal, and :unknown,
# corresponding to the log level numbers from 0 up to 5 respectively
config.log_level = :info
config.log_level = :debug
# for finding database optimization
config.after_initialize do
Bullet.enable = true
Bullet.bullet_logger = true
Bullet.rails_logger = true
Bullet.raise = true # raise an error if n+1 query occurs
Bullet.unused_eager_loading_enable = false
# Currenty hard to fix, it is triggered by Epp::Domain.new_from_epp for create request
Bullet.add_whitelist type: :n_plus_one_query, class_name: 'Contact', association: :registrar
# when domain updates, then we need to update all contact linked status,
# somehow it triggers bullet counter cache for versions,
# there was no output indicating each version where fetched or counted
# thus needs more investigation
Bullet.add_whitelist type: :counter_cache, class_name: 'Contact', association: :versions
end
# config.logger = Logger.new(STDOUT)
end
# In this mode, any jobs you queue will be run in the same thread, synchronously