Как запустить какое-то действие каждые несколько секунд на 10 минут в рельсах? - PullRequest
0 голосов
/ 28 апреля 2018

Я пытаюсь создать приложение, похожее на викторину, и хочу отправлять трансляцию каждые 10 секунд со случайным вопросом в течение 2 минут. Как мне это сделать с помощью рельсов? Я использую кабель действия для отправки трансляции. Я могу использовать rufus-scheduler для запуска действия каждые несколько секунд, но я не уверен, имеет ли смысл использовать его для моего случая использования.

1 Ответ

0 голосов
/ 30 апреля 2018

Самое простое решение - создать новый поток:

Thread.new do
  duration = 2.minutes
  interval = 10.seconds
  number_of_questions_left = duration.seconds / interval.seconds

  while(number_of_questions_left > 0) do
    ActionCable.server.broadcast(
      "some_broadcast_id", { random_question: 'How are you doing?' }
    )
    number_of_questions_left -= 1
    sleep(interval)
  end
end

Примечания:

  • Это только простое решение, из которого вы фактически заканчиваете более 2 минут общего времени выполнения, потому что каждый цикл фактически спит чуть более 10 секунд. Если это несоответствие не важно, то вышеупомянутого решения уже будет достаточно.

  • Кроме того, этот тип планировщика сохраняется только в памяти, в отличие от выделенного фонового работника, такого как sidekiq. Таким образом, если процесс rails будет прерван, то и весь выполняющийся в данный момент «зацикленный» код также будет прерван, чего вы можете намеренно хотеть или не хотеть.

При использовании rufus-scheduler:

number_of_questions_left = 12

scheduler = Rufus::Scheduler.new

# `first_in` is set so that first-time job runs immediately
scheduler.every '10s', first_in: 0.1 do |job|
  ActionCable.server.broadcast(
    "some_broadcast_id", { random_question: 'How are you doing?' }
  )
  number_of_questions_left -= 1
  job.unschedule if number_of_questions_left == 0
end
...