Skip to content

Commit

Permalink
use actioncable to track indexing progress
Browse files Browse the repository at this point in the history
  • Loading branch information
dnoneill committed Oct 9, 2024
1 parent e98d75c commit 5f4c782
Show file tree
Hide file tree
Showing 23 changed files with 1,334 additions and 120 deletions.
550 changes: 527 additions & 23 deletions app/assets/javascripts/spotlight/spotlight.esm.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion app/assets/javascripts/spotlight/spotlight.esm.js.map

Large diffs are not rendered by default.

550 changes: 527 additions & 23 deletions app/assets/javascripts/spotlight/spotlight.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion app/assets/javascripts/spotlight/spotlight.js.map

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions app/channels/application_cable/channel.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

module ApplicationCable
class Channel < ActionCable::Channel::Base
end
end
6 changes: 6 additions & 0 deletions app/channels/application_cable/connection.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

module ApplicationCable
class Connection < ActionCable::Connection::Base
end
end
8 changes: 8 additions & 0 deletions app/channels/progress_channel.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

# Channel for receiving indexing progress
class ProgressChannel < ApplicationCable::Channel
def subscribed
stream_from 'progress_channel'
end
end
30 changes: 30 additions & 0 deletions app/components/spotlight/progress_bar_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<div data-behavior='progress-panel' data-exhibit-id="<%= exhibit.id %>">
<div class="card index-status border-info mb-3">
<h3 class="card-header bg-info text-white h4"><%= t("#{translation_field}.heading") %></h3>
<div class="card-body">
<p data-behavior='monitor-start'>
<span class="text-muted" data-behavior='date'></span> <%= t("#{translation_field}.begin_html") %>
</p>

<% if I18n.exists?("#{translation_field}.current_html") %>
<p data-behavior='monitor-current'>
<span class="text-muted" data-behavior='date'></span> <%= t("#{translation_field}.current_html") %>
</p>
<% end %>

<% if I18n.exists?("#{translation_field}.completed_html") %>
<p data-behavior='monitor-completed'>
<span class="text-muted" data-behavior='date'></span> <%= t("#{translation_field}.completed_html") %>
</p>
<% end %>

<p class="bg-warning" data-behavior='monitor-error' style='display:none;'>
<%= t("#{translation_field}.error") %>
</p>

<div class="progress">
<div class="progress-bar progress-bar-striped active" role="progressbar" aria-valuenow="" aria-valuemin="0" aria-valuemax=""></div>
</div>
</div>
</div>
</div>
14 changes: 14 additions & 0 deletions app/components/spotlight/progress_bar_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

module Spotlight
# Renders progress bar html which is updated by progress_monitor.js
class ProgressBarComponent < ViewComponent::Base
attr_reader :exhibit, :translation_field

def initialize(exhibit:, translation_field:)
@exhibit = exhibit
@translation_field = translation_field
super
end
end
end
32 changes: 9 additions & 23 deletions app/javascript/spotlight/admin/progress_monitor.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import consumer from "../channels/consumer"

export default class {
connect() {
var monitorElements = $('[data-behavior="progress-panel"]');
var defaultRefreshRate = 3000;
var panelContainer;
var pollers = [];

$(monitorElements).each(function() {
panelContainer = $(this);
panelContainer.hide();
var monitorUrl = panelContainer.data('monitorUrl');
var refreshRate = panelContainer.data('refreshRate') || defaultRefreshRate;
pollers.push(
setInterval(function() {
checkMonitorUrl(monitorUrl);
}, refreshRate)
);

consumer.subscriptions.create({ channel: "ProgressChannel"}, {
received(data) {
if (data.exhibit_id != panelContainer.data('exhibit-id')) return;
updateMonitorPanel(data);
}
});
});

// Clear the intervals on turbolink:click event (e.g. when the user navigates away from the page)
Expand All @@ -27,21 +28,6 @@ export default class {
}
});

function checkMonitorUrl(url) {
$.ajax(url).done(success).fail(fail);
}

function success(data) {
if (data.recently_in_progress) {
updateMonitorPanel(data);
monitorPanel().show();
} else {
monitorPanel().hide();
}
}

function fail() { monitorPanel().hide(); }

function updateMonitorPanel(data) {
panelStartDate().text(data.started_at);
panelCurrentDate().text(data.updated_at);
Expand Down
6 changes: 6 additions & 0 deletions app/javascript/spotlight/channels/consumer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Action Cable provides the framework to deal with WebSockets in Rails.
// You can generate new channels where WebSocket features live using the `bin/rails generate channel` command.

import { createConsumer } from "@rails/actioncable"

export default createConsumer()
1 change: 1 addition & 0 deletions app/javascript/spotlight/channels/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// Import all the channels to be used by Action Cable
10 changes: 10 additions & 0 deletions app/jobs/spotlight/process_bulk_updates_csv_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,25 @@ def perform(exhibit, bulk_update)
errors = 0
header_converter = ->(header) { header } # Use raw header for columns (since they are configured)
csv_path = bulk_update.file.current_path
started_at = Time.zone.now

File.open(csv_path) do |f|
progress&.total = f.each_line.count(&:present?) - 1 # ignore the header

::CSV.table(f, header_converters: header_converter).each do |row|
process_row(exhibit, row)
progress&.increment
ActionCable.server.broadcast 'progress_channel',
{ exhibit_id: exhibit.id, finished: progress.progress == progress.total,
completed: progress.progress, total: progress.total, errors: errors,
updated_at: Time.zone.now, started_at: started_at }
rescue StandardError => e
job_tracker.append_log_entry(type: :error, exhibit: exhibit, message: e.to_s)
errors += 1
ActionCable.server.broadcast 'progress_channel',
{ exhibit_id: exhibit.id, finished: progress.progress == progress.total,
completed: progress.progress, total: progress.total, errors: errors,
updated_at: Time.zone.now, started_at: started_at }
mark_job_as_failed!
end

Expand Down
10 changes: 10 additions & 0 deletions app/jobs/spotlight/reindex_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,22 @@ def perform(exhibit_or_resources, start: nil, finish: nil, **)
errors += 1
end

started_at = Time.zone.now

resource_list(exhibit_or_resources, start: start, finish: finish).each do |resource|
resource.reindex(touch: false, commit: false, job_tracker: job_tracker, additional_data: job_data, on_error: error_handler) do |*|
progress&.increment
ActionCable.server.broadcast 'progress_channel',
{ exhibit_id: resource.exhibit_id, finished: progress.progress == progress.total,
completed: progress.progress, total: progress.total, errors: errors,
updated_at: Time.zone.now, started_at: started_at, other: resource }
end
rescue StandardError => e
error_handler.call(Struct.new(:source).new(resource), e, nil)
ActionCable.server.broadcast 'progress_channel',
{ exhibit_id: resource.exhibit_id, finished: progress.progress == progress.total,
completed: progress.progress, total: progress.total, errors: errors,
updated_at: Time.zone.now, started_at: started_at, other: resource }
end

job_tracker.append_log_entry(
Expand Down
19 changes: 0 additions & 19 deletions app/views/spotlight/bulk_updates/_progress_panel.html.erb

This file was deleted.

4 changes: 1 addition & 3 deletions app/views/spotlight/bulk_updates/edit.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@

<%= curation_page_title t(:".header") %>

<div data-behavior='progress-panel' data-monitor-url="<%= monitor_exhibit_bulk_updates_path(current_exhibit) %>">
<%= render 'progress_panel' %>
</div>
<%= render Spotlight::ProgressBarComponent.new(exhibit: current_exhibit, translation_field: 'spotlight.bulk_updates.progress_panel') %>

<div role="tabpanel">
<ul class="nav nav-tabs" role="tablist">
Expand Down
4 changes: 1 addition & 3 deletions app/views/spotlight/catalog/_admin_header.html.erb
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
<% if can? :manage, Spotlight::Resource.new(exhibit: current_exhibit) %>
<div data-behavior='progress-panel' data-monitor-url="<%= monitor_exhibit_resources_path(current_exhibit) %>">
<%= render 'reindex_progress_panel' %>
</div>
<%= render Spotlight::ProgressBarComponent.new(exhibit: current_exhibit, translation_field: 'spotlight.catalog.reindex_progress_panel') %>
<div class="add-items-nav clearfix">
<div class="float-right float-end">
<%= link_to t('.reindex'), reindex_all_exhibit_resources_path(current_exhibit),
Expand Down
19 changes: 0 additions & 19 deletions app/views/spotlight/catalog/_reindex_progress_panel.html.erb

This file was deleted.

7 changes: 7 additions & 0 deletions config/cable.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
development:
adapter: async

production:
adapter: redis
url: redis://localhost:6379/1
channel_prefix: myapp_production
Loading

0 comments on commit 5f4c782

Please sign in to comment.