Как правильно применить delayed_job для создания повторяющихся событий?

Добрый день, господа. Прошу прощения за, возможно, глупый вопрос, но понимание никак не приходит.
Есть задача: нужно создавать события в календаре, в зависимости от атрибута модели(:repeat) событие может быть ежедневным, еженедельным, ежемесячным, ежегодным. В каждом конкретном случае создается набор событий вперед (на каждый день, месяц, неделю, год). Поскольку создание 365 событий занимает много времени, процесс уводится в фоновый режим(поток). Вот мой метод create:

def create
    @event = current_user.events.create(event_params)

    Thread.new do
      case @event.every
        when 1 
          for i in 1..365
            @event = current_user.events.create(event_params)
            @event.update_attributes( start_at: @event.start_at + i.day )
            @event.update_attributes( end_at: @event.end_at + i.day )
          end
        when 2 
          for i in 1..53
            @event = current_user.events.create(event_params)
            @event.update_attributes( start_at: @event.start_at + i.week )
            @event.update_attributes( end_at: @event.end_at + i.week )
          end
        when 3 
          for i in 1..11
            @event = current_user.events.create(event_params)
            @event.update_attributes( start_at: @event.start_at + i.month )
            @event.update_attributes( end_at: @event.end_at + i.month )
          end
        when 4 
          for i in 1..10
            @event = current_user.events.create(event_params)
            @event.update_attributes( start_at: @event.start_at + i.year )
            @event.update_attributes( end_at: @event.end_at + i.year )
          end
      end
    end
  end


Как переделать сие, применив гем delayed_job? Где правильнее всего хранить всю эту логику? Разумно ли оставить все в методе контроллера? Заранее спасибо за помощь.
  • Вопрос задан
  • 366 просмотров
Решения вопроса 2
@vsuhachev
Я бы на вашем месте не планировал все события наперед, а планировал ближайшее событие. А после его исполнения планировал следующее и т.п. Сейчас же у вас все жестко забито в коде, например ежедневное событие через год перестанет исполняться, а ежегодное через 10 лет.

Итого вам нужно
1) Хранить где-то запись о том что задача X запланирована с даты Y с периодичностью Z
2) Хранить запись о истории выполнения событий из которой можно узнать когда последний раз выполнялась задача X
3) Фоновая задача по планированию событий, которая будет выполняться например 1 раз в час и будет читать данные из пп.1-2 и создавать следующее приближающееся событие.
Ответ написан
2ord
@2ord
Создай модель
class JobCreateEvents < Struct.new(:event_id, user_id)
  def perform
    user = User.find(user_id)
    event = Event.find(event_id)
    # ...
    # долгая операция
    # ...
  end
end


Затем в контроллере помещаешь операцию по созданию событий в очередь:
Delayed::Job.enqueue JobCreateEvents.new(@event.id, @current_user.id)


Thread.new убираешь.

Логику можно хранить как в модели JobCreateEvents, так и в модели Event.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
ruddy22
@ruddy22
Спасение утопающих — дело рук самих утопающих
Лучше не пользоваться delayed_job. Используйте Resque, sidekiq, active_job
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы