0

I have a long running job that scrapes information from the internet (approx 2 mins) and I am having trouble with updating my pages/views with the new (additional) instances of the data that I scrape.

I thought it might be doable with a callback (on create/update) but I get an error saying I am redirecting too many times, so I figured I would most likely need some ajax and/or callback combination in order to achieve a continuous updating of the page. Im familiar with using ajax in order to update a section of the page when the user creates a post or comment but Im not sure how to do this coming from a background job. I briefly toyed with using ActionCable (just opening a channel and somehow stream the data through there) but is there not an easier way to essentially update the page on a change in the database? My current solution is to simply js reload the page for a while but that seems awefully primitive.

Controller

def create
  @search = Search.new(search_params)
  if @search.save
    PreRunAllJob.perform_later(@search.title, @search.id)
    respond_to do |format|
      format.html { redirect_to search_path(@search) }
      format.js # currently empty
    end
  else
    render :new
  end
end

def show
  @search = Search.find(params[:id])
  @jobs = Job.where(search_id: @search.id).order(quality: :desc)
end

Search Model

class Search < ApplicationRecord
  has_many :jobs
end

Job Model

class Job < ApplicationRecord
  belongs_to :search
end

searches/show.html.erb

<div class="container">
  <%= render "jobs", remote: true %>
</div>

_jobs.html.erb

[...]
<% @jobs.each do |job| %>
  <div class="card">
    [...]
  </div>
<% end %>
[...]

So just to quickly summarise: The long running background job creates an instance of 'Search' which has many instances of 'Job'. On the searches/show.html.erb I display cards, each holding information of a single instance of 'Job'. While the search is ongoing I'd like to update the view correspondingly (trickling in for instance). What path could/should I take here? pure ajax? Callbacks?

Haumer
  • 460
  • 4
  • 15
  • 1
    You can do ajax polling (doing ajax requests continuously to check if something changed), yes, but that's the problema websockets (actioncable) solve. Websockets is a bidirectional connection between the client and the server, so the server can send messages to the clients. Ajax polling is a one directional connection, the server can only respond to clent's requests. Using ActionCable is actually not that hard, I'd suggest you to read ActionCable tutorials, the basic example is to build a chat, but it's always the same idea, you have javascript callbacks that receive messages from the server. – arieljuod Feb 16 '19 at 23:13
  • 1
    You could use push notifications but you'll depend on the user accepting the push api usage and also on a third party service to handle them. – arieljuod Feb 16 '19 at 23:15
  • This might help you: https://stackoverflow.com/questions/39586846/how-to-listen-for-database-changes-triggered-by-a-3rd-party-application – mehedi Feb 17 '19 at 10:58

0 Answers0