2015-12-28 2 views
2

У меня есть метод, который обновляет все записи DNS для учетной записи с 1 задержкой для каждой записи. Там много рабочих и очередей, что отлично подходит для быстрого выполнения других заданий, но эта конкретная работа быстро завершается и подавляет базу данных. Поскольку каждое задание требует разрешения DNS, трудно переместить это в процесс, который собирает информацию, а затем записывает один раз. Поэтому я вместо этого ищу способ замедлить работу с задержкой.Задержка отложенного задания DB

Насколько я знаю, просто используя sleep(0.1) в методе after должен сделать трюк. Я хотел посмотреть, не обратил ли кто-либо другой конкретный вопрос на эту ситуацию и решил ли это.

Я создал специальную работу, чтобы протестировать несколько разных идей. Вот пример кода:

def update_dns 
    Account.active.find_each do |account| 
    account.domains.where('processed IS NULL').find_each do |domain| 
     begin 
     Delayed::Job.enqueue StaggerJob.new(self.id) 
     rescue Exception => e 
     self.domain_logger.error "Unable to update DNS for #{domain.name} (id=#{domain.id})" 
     self.domain_logger.error e.message 
     self.domain_logger.error e.backtrace 
     end 
    end 
    end 
end 

Когда хрон работа вызывает Domain.update_dns, просроченную работу столов наводнения с десятками тысяч рабочих мест, а также рабочие начинают работать через них. Там так много рабочих и очередей, которые даже устанавливают самый низкий приоритет, подавляет базу данных и другие запросы.

Вот класс StaggerJob:

class StaggerJob < Struct.new(:domain_id) 

    def perform 
    domain.fetch_dns_job 
    end 

    def enqueue(job) 
    job.account_id  = domain.account_id 
    job.owner   = domain 
    job.priority  = 10 # lowest 
    job.save 
    end 

    def after(job) 
    # Sleep to avoid overwhelming the DB 
    sleep(0.1) 
    end 

    private 
    def domain 
     @domain ||= Domain.find self.domain_id 
    end 

end 

Это может полностью сделать трюк, но я хотел бы проверить, если этот метод был разумным.

+0

Я не уверен, в чем проблема, не могли бы вы поделиться примером кода? и объяснить больше? –

+0

При условии, что некоторые детали – Archonic

+0

Итак, проблема слишком много заданий для Delayed Job? –

ответ

0

Оказалось, что приоритет для этих заданий был установлен на 0 (самый высокий). Устанавливается значение 10 (самый низкий). Сон в работе после метода будет работать, но есть лучший способ.

Delayed::Job.enqueue StaggerJob.new(domain.id, :fetch_dns!), run_at: (Time.now + (0.2*counter).seconds) # stagger by 0.2 seconds 

Это в конечном итоге приостанавливается вне работы, а не внутри. Лучше!

Смежные вопросы