Rails и sucker_punch: отладка x секунд перед выполнением задания для контроля скорости выполнения
В моем проекте Rails 3.2 я использую SuckerPunch для запуска дорогостоящей фоновой задачи при создании / обновлении модели.
Пользователи могут выполнять различные типы взаимодействий в этой модели. В большинстве случаев эти обновления довольно хорошо разнесены, однако для некоторых других действий, таких как переупорядочение, массовые обновления и т. Д., Эти запросы POST могут приходить очень часто, и именно тогда они перегружают сервер.
Мой вопрос заключается в том, что было бы наиболее элегантной / умной стратегией для запуска фонового задания при первом обновлении, но подождите, скажем, 10 секунд, чтобы убедиться, что больше не поступают обновления для этой модели (таблица, а не строка), а затем выполнить работу. Так эффективно дросселирует без очереди.
мой sucker_punch
рабочий выглядит примерно так:
class StaticMapWorker
include SuckerPunch::Job
workers 10
def perform(map,markers)
#perform some expensive job
end
end
Это вызывается из Marker
и модель "Карта", а иногда и из контроллеров (для update_all
случаи) вроде так:
after_save :generate_static_map_html
def generate_static_map_html
StaticMapWorker.new.async.perform(self.map, self.map.markers)
end
Итак, довольно стандартная настройка для запуска фоновой работы. Как заставить работу ждать или не планировать, пока не появятся обновления для x seconds
на моей модели (или таблицы)
Если это поможет, карта has_many
Маркеры настолько запускают работу с логикой, что при любой ассоциации маркеров обновления карты тоже будет в порядке.
1 ответ
То, что вы ищете, это отложенные вакансии, реализованные через ActiveJob's perform_later
, Согласно руководствам по краю, это не реализовано в sucker_punch
,ActiveJob::QueueAdapters
сравнение
Не беспокойтесь, потому что вы можете реализовать это самостоятельно довольно просто. Когда ваша работа получает работу из очереди, сначала выполните некоторые математические операции с записями. modified_at
отметка времени, сравнивая ее с 10 секундами назад. Если модель была изменена, просто добавьте задание в очередь и аккуратно прервите.
код!
В соответствии с примером 2/5 пути вниз по странице, объясняющим, как добавить работу в рабочий присоски Github
class StaticMapWorker
include SuckerPunch::Job
workers 10
def perform(map,markers)
if Map.where(modified_at: 10.seconds.ago..Time.now).count > 0
StaticMapWorker.new.async.perform(map,markers)
else
#perform some expensive job
end
end
end