ruby - Rails: update controller with sidekiq result -
good morning!
i have form takes in ip, start date, , stop date calls sidekiq worker executes script on external server through ssh, sftps resulting file local server.
controller method:
def create @script = script.new(params[:script]) if @script.valid? @job_id = logsworker.perform_async(@script.ip, @script.start_date, @script.stop_date) else render :action => 'new' end end
sidekiq worker:
def perform(ip, start_date, stop_date) net::ssh.start('server', 'username') |ssh| result = ssh.exec!("<script here> #{ip} #{start_date} #{stop_date}") ssh.sftp.connect |sftp| local_result = "#{rails.root}/public/uploads/" + file.basename(result) sftp.download!(result, local_result) end end .. continued ..
i have sidekiq worker parse resulting file hash:
.. continuing .. @file_hash = {} = 0 file.open(local_result, "r") |fp| fp.each_line |line| ip, date, method, url_full = line.split("\t") @file_hash[i] = {ip: ip, date: date, method: method, url_full: url_full} += 1 end end end
and partial _results.html.erb
parses it:
<% if @file_hash %> <% @file_hash.each |key, value| %> <tr> <td><%= value[:ip] %></td> <td><%= value[:date] %></td> <td><%= value[:method] %></td> <td><%= value[:url_full] %></td> </tr> <% end %> <% end %>
i tried rendering results after job has completed <%= render partial: 'results', locals: { file_hash: @file_hash } %>
in create.js.coffee file, not think has idea instance variable.
how can pass result completed sidekiq variable view? think should note have controller method queries completion percentage of sidekiq job, should able tell when finished.
edit:
percentage_done
in controller
def percentage_done job_id = params[:job_id] # grabbing job_id params container = sidekiqstatus::container.load(job_id) @pct_complete = container.pct_complete respond_to |format| format.json { render :json => { :percentage_done => @pct_complete, # responding json percent complete data } } end end
current ajax
queryforpercentage = () -> job_id = $('#job_id').text() # grabbing job_id $.ajax({ url: "/percentage_done" # sending ajax request /percentage_done data: job_id: job_id # using job_id dom success: (data) -> # executed after successful call percentage_done controller percentage = 'width: ' + data['percentage_done'] + '%;' # writing percentage done progress bar $('#job-progress').attr('style', percentage).text(data['percentage_done'] + '%') $('#job-progress').attr('aria-valuenow', data['percentage_done']) if $('#job-progress').text() != '100%' settimeout((-> queryforpercentage()), 1500) else # replace html of div script_lists updated new 1 $("#scripts_list").html("<%= escape_javascript(render partial: 'results', locals: { file_hash: @file_hash } ) %>"); }) queryforpercentage()
sidekiq used process background jobs. imo sending result sidekiq job view defeats purpose of using sidekiq; why not perform job in same request.
with said, accomplish ajax call on view polls controller queries sidekiq completion. controller can return contents of file. if sidekiq job doesn't take long complete might not bad user experience.
Comments
Post a Comment