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:
My view:
<%= form_tag(:controller => 'home', :action => 'start') do %>
<%= submit_tag "Start Checking for new Data", :class => "btn btn-success btn-lg btn-start" %>
<% end %>
My Controller:
def start
if current_user
begin
Poller.delay.do_something(client)
flash[:notice] = 'Polling Started'
rescue
flash[:error] = 'Issue connecting to API. Please try again later.'
end
redirect_to :back
end
end
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 start
method?
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.
Poller
for any other user until the current Poller
finishes.stop
signal, you probably want to stop anyway after some limit.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.