задания cron в ROR 3

Часто возникает необходимость в приложениях на рельсах запускать какие-то скрипты cron’ом. Однако, желательно не просто запустить скрипт, для этого особого ума не надо, а написать скрипт и запустить его так чтобы он использовал интерфейсы Rails т.е. ROR-методы работы с БД, короче говоря Active Records.

Способами как сделать cron-скрипт для Rails 2.x исписан весь интернет. Собственно в Rails 3.x все практически также.

Открываем какую-нибудь модель или создаем новую, пусть это будет rails_app/app/models/product.rb:

1
2
3
class Product < ActiveRecord::Base
#возможно здесь что-то есть
end

И дописываем в класс метод собственно с самим нашим заданием, например:

1
2
3
4
5
6
7
class Product < ActiveRecord::Base
  def crontask
    fl=File.new('crontask_result','w')
    fl.puts Time.now
    fl.close
  end
end

А теперь чтобы запустить написанный метод пишем в консоли или cron’е так:

1
2
$ RAILS_ENV=production ruby
rails_app/script/rails runner Product.crontask

В результате чего в корне rails_app будет создан файл crontask_result со временем запуска скрипта.

Это все понятно и легко, но порой при запуске методов, написанных под крон вылетает ошибка а-ля:

1
2
3
/usr/local/lib/ruby/gems/1.9.1/gems/railties-3.0.3/lib/rails
/commands/runner.rb:50:in `eval': "\x8B" from
ASCII-8BIT to UTF-8 (Encoding::UndefinedConversionError)

Почитав переписку самого Юкихиро Мацумото со многими, я так понил, что этот баг не исправлен. Поэтому решаем эту проблему тупо в лоб, разбиваем метод, на части:

  • где содержатся или обрабатываются не ASCII символы переносим в отдельные скрипты, не связанные с Rails
  • где все ASCII пишем в метод и через system() вызываем первую категорию скриптов, а также здесь осуществляем необходимую связь первых скриптов с Rails Active Records

Как будут передаватся данные из первых скриптов вторым абсолютно все равно, через временные файлы, сокеты, кодом завершения итд.

У кого есть варианты получше пишите в комментариях.

5 Comments to “задания cron в ROR 3”

  1. Pavel пишет:

    А можно и вообще крон не использовать:
    https://github.com/javan/whenever

  2. lukmus пишет:

    посмотрел, прикольная штука.
    Единственное, я думаю что жрет процессора она больше чем крон т.к. Руби не Си

  3. lukmus пишет:

    чтобы не забыть.
    Лучше запускать кроновый методы не так как я писал выше (в том случае Active Records может не работать), а так:

    • из корня
      rails runner -e production 'Product.crontask'
    • не из корня
      ruby rails_app/script/rails runner -e production 'Product.crontask'
  4. Leonid Shevtsov пишет:

    В Rails общепринятый метод писать скрипты, запускаемые с командной строки – Rake. Вот, например, нисколько не устаревший рельскаст на эту тему: http://railscasts.com/episodes/66-custom-rake-tasks

    Преимущества Rake-тасок перед тем, что вы делаете – в первую очередь, то, что они наглядны.

    Кстати, whenever – это удобный способ наполнять crontab из руби, не более того (и очень полезный). Это не самостоятельный планировщик, не знаю где вы это вычитали, и ресурсов он не ест в принципе.

  5. [...] rake. Об этом способе я узнал из  комментария к статье задания cron в ROR 3, который написал Леонид Шевцов, приведя ссылку на [...]

Leave a Reply to Pavel

(обязательно)

(обязательно)