Search code examples
ruby-on-railsrubyrakeactioncablerails-activejob

How to run some action every few seconds for 10 minutes in rails?


I am trying to build quizup like app and want to send broadcast every 10 second with a random question for 2 minutes. How do I do that using rails ? I am using action cable for sending broadcast. I can use rufus-scheduler for running an action every few seconds but I am not sure if it make sense to use it for my use case .


Solution

  • Simplest solution would be to fork a new thread:

    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
    

    Notes:

    • This is only a simple solution of which you are actually ending up more than 2.minutes of total run time, because each loop actually ends up sleeping very slightly more than 10 seconds. If this discrepancy is not important, then the solution above would be already sufficient.

    • Also, this kind-of-scheduler only persists in memory, as opposed to a dedicated background worker like sidekiq. So, if the rails process gets terminated, then all currently running "looping" code will also be terminated as well, which you might intentionally want or not want.

    If using 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