Подтвердить что ты не робот

Как выполнить некоторую задачу после рендеринга в Rails 3.1

Я использую Impressionist, чтобы записывать показы страниц. Запись базы данных занимает всего около 50 мс, но я бы предпочел сделать это после того, как страница была отображена и отправлена ​​клиенту.

Я искал forking через Spawn, но он устанавливает новое соединение с базой данных, которое, кажется, слишком велико для такого небольшого работа. Задержка работы и другие библиотеки обработки фонограмм кажутся серьезным излишеством. Запись в базу данных просто для отсрочки записи в базу данных... не выигрыш.

Хотел бы я просто:

def show
  render
  impressionist(@article)
end

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

Любые решения? Running Rails 3.1 и Ruby 1.9.2 на кедрах Героку.

4b9b3361

Ответ 1

Создайте новый поток. Heroku позволит вам до 15 потоков на дино.

def show
  render
  Thread.new do
    impressionist(@article)
  end
end

Ответ 2

Есть довольно классный railscast об использовании Resque для этого, но я уверен, что он также включает в себя forking, как и все другие методы, которые я видел.

Ответ 3

Это получилось и выглядит многообещающим: https://github.com/brandonhilkert/sucker_punch

Брэндон крепкий чувак. Не могу дождаться, чтобы попробовать Sucker Punch!

Ответ 4

Лично я бы не рекомендовал запускать "Thread new" из действия, а затем передать ссылку на фоновый поток на элементы (элементы), которые все еще обрабатываются в другом потоке. Это очень быстро приводит к неприятным неповторяемым ошибкам из-за конфликтов между потоками.

Ответ 5

Как насчет входа в нечто более быстрое, например, mongodb, или вы можете подумать о сохранении хэша в redis (сверхбыстрый) и запустить пакетное задание каждый час или около того, чтобы сохранить их в своей базе данных postgres. С обоими этими параметрами вам придется взломать импрессионист или создать собственное решение, которое, как вы предложили с помощью фоновых решений (delayed_job, resque и т.д.), Может быть переборщиком в зависимости от размера вашего проекта.

Ответ 6

Я думаю, вы можете использовать функцию обратного вызова after_filter

class ApplicationController < ActionController::Base

  after_filter :after_filter_cb

  def after_filter_cb
    # Some logic
  end

end