Search code examples
ruby-on-railsbackground-processrails-activejob

Start job from another job


Here is what I'm trying to achieve: As a user, I can book a spot for a class. If the class is already full, I'll be on the waiting list. When a new spot is available, I'll receive an email. From then, the app starts a background job that will "wait" 24h. If I haven't confirmed that I'm taking the spot before 24h, it is attributed to the next person on the waiting list, who will also have to confirm before 24h.

The problem is when passing the spot to the next person on the list: since I'm already in the "timer job", I need to call it again with the next person.

class TimerJob
  def perform(user_id)
    send_confimation_email
    if #didn't confirm before 24h
      TimerJob.perform(next_user_on_list_id)
    else
      # save his spot
    end 
  end 
end

The first job works fine, it sends an email, waits for a confirmation within 24h, and then sends another email to the next person on the list but doesn't start another job (line 5). So it won't start the process again if the 24h wait is over.

So the question would be: how can I call a job within a job like in my example ? Is there a reason why this isn't working ?

Or am I over complicating this and a fresh eye would have an easier solution ?

I thought of calling a module from within the job, which would basically call back the job. But same here, didn't work. Any input will be much appreciated.


Solution

  • The code you've posted should work in terms of enqueueing the job, however it's not clear from the code you've posted at which point the "wait 24 hours" part of your workflow is happening. It looks as though your TimerJob sends an email and then immediately checks for the confirmation.

    To my mind it would make more sense to send an email immediately on signup and to enqueue a job with TimerJob.perform_in(24.hours, next_user_id) which checks if the email was confirmed. Then if it was not you can send another email/queue another job in 24 hours more.