2012-06-01 2 views
0

Я хотел бы добавить что-то вроде «фоновой» нити в приложение для рельсов. Мне нужно время от времени проверять электронные письма (скажем, каждые 10 минут), а затем делать что-то по электронной почте. Это должно работать так же, как работают трекеры ошибок, вы можете ответить на сообщение электронной почты, которое вы получили от трекера ошибок, и оно отправит электронное письмо и добавит его в билет.Фоновая рабочая нить для рубина

Есть ли какой-нибудь простой способ запускать что-то подобное в фоновом режиме? Я не хочу использовать cron или любые системные инструменты, просто чистый рубин. Я запускаю приложение, и мне все равно не нужно.

ответ

3

EventMachine есть PeriodicTimer

n = 0 
timer = EventMachine::PeriodicTimer.new(5) do 
    puts "the time is #{Time.now}" 
    timer.cancel if (n+=1) > 5 
end 

rufus-scheduler является инструментом хрон типа записи в чистом Ruby, базовой EventMachine.

+0

Руфус-планировщик больше не основан на EventMachine. – Sim

0

Отъезд Daemon-Kit. Это позволяет создавать Ruby Daemons в рамках с аналогичными соглашениями с проектами Rails. Мы используем его для мониторинга и выполнения различных фоновых задач.

0

Я использую delayed_job в своем проекте.

Delayed_job (или DJ) инкапсулирует общую схему асинхронного выполнения более длинных задач в фоновом режиме.

1

Есть пара потенциальных проблем с принятым ответом, который стоит указать.

Во-первых, PeriodicTimer выполняет саморегуляцию для выполнения с использованием рекурсии хвоста, то есть путем вызова EventMachine.add_timer после выполнения его блока. К сожалению, код не использует begin-ensure-end, что означает, что если в вашем коде есть исключение, таймер остановится. См. GH#454.

Во-вторых, существует вопрос о том, что реакторный контур EventMachine работает в одном потоке как однотонный. Если вы запустите PeriodicTimer и выполните медленные операции электронной почты в своем блоке, вы заблокируете петлю реактора, от которой может зависеть другой код. Лучше всего подтолкнуть работу по сбору электронной почты к отдельной теме, используя EventMachine::Deferrable. См. Пример this post.

И последнее, но не менее важное: вы должны запускать EventMachine в отдельной ветке, если его реактор еще не работает, но вы должны «запланировать» работу над потоком реактора, если он уже запущен.

Сведя вместе у вас есть что-то вдоль линий:

def check_email 
    timer = EM::PeriodicTimer.new(10.minutes) do 
    begin 
     DefferableEmailChecker.new.errback do |error| 
     # handle error 
     # note that this code will run OUTSIDE the 
     # periodic timer block 
     end 
    rescue Exception => e 
     # even with a Deferable this is good practice 
     # if you want to cancel, use timer.cancel 
    end 
    end 
end 

if EM.reactor_running? 
    EM.schedule do 
    check_email 
    end 
else 
    Thread.new do 
    EM.run do 
     check_email 
    end 
    end 
end 
Смежные вопросы