I am using delayed job to run a specific method in the background, and I need to keep running this method indefinitely, until it is stopped by the user. I have this set up as follows:
I have a button in my view which calls a controller method as follows:
<%= form_tag(:controller => 'home', :action => 'start') do %>
<%= submit_tag "Start Checking for new Data", :class => "btn btn-success btn-lg btn-start" %>
<% end %>
flash[:notice] = 'Polling Started'
flash[:error] = 'Issue connecting to API. Please try again later.'
How can I allow the user to
Start checking for new data by calling the
start method over and over? Also, how can I allow them to
Stop checking for new data by calling a method which will stop calling the
Best How To :
A first step would be to have your
Poller job check some model attribute on each iteration looking for some signal to end it's loop. Rather than trying to interrupt the
Poller let it finish the current iteration but check if it should continue before looping.
However there are still problems with this pattern overall and I encourage you to reconsider background jobs which loop forever.
- This job will block a worker and prevent that worker from running a
Poller for any other user until the current
- The user may not choose or be able to send a
stop signal, you probably want to stop anyway after some limit.
- It seems unlikely that you really want to poll whatever endpoint you are using as fast as possible. Rather than spin a worker waiting during each iteration it would be nice if that worker were available to handle other jobs instead.
A better solution might be to have your
Poller job run once and then enqueue a copy of itself when it finishes if the polling should continue. Your worker can then interleave
Poller jobs from many users. Much like above each job can check some model state or method to determine if it should enqueue another poll action or not. Depending on how you run those jobs it may also be easier to schedule future iterations with some delay to throttle your polling.