Skip to content

Commit e491011

Browse files
committed
use actioncable to track indexing progress
1 parent e98d75c commit e491011

23 files changed

+1334
-120
lines changed

app/assets/javascripts/spotlight/spotlight.esm.js

Lines changed: 527 additions & 23 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/assets/javascripts/spotlight/spotlight.esm.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/assets/javascripts/spotlight/spotlight.js

Lines changed: 527 additions & 23 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/assets/javascripts/spotlight/spotlight.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# frozen_string_literal: true
2+
3+
module ApplicationCable
4+
class Channel < ActionCable::Channel::Base
5+
end
6+
end
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# frozen_string_literal: true
2+
3+
module ApplicationCable
4+
class Connection < ActionCable::Connection::Base
5+
end
6+
end

app/channels/progress_channel.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# frozen_string_literal: true
2+
3+
# Channel for receiving indexing progress
4+
class ProgressChannel < ApplicationCable::Channel
5+
def subscribed
6+
stream_from 'progress_channel'
7+
end
8+
end
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<div data-behavior='progress-panel' data-exhibit-id="<%= exhibit.id %>">
2+
<div class="card index-status border-info mb-3">
3+
<h3 class="card-header bg-info text-white h4"><%= t("heading", scope: translation_field) %></h3>
4+
<div class="card-body">
5+
<p data-behavior='monitor-start'>
6+
<span class="text-muted" data-behavior='date'></span> <%= t("begin_html", scope: translation_field) %>
7+
</p>
8+
9+
<% if I18n.exists?("current_html", scope: translation_field) %>
10+
<p data-behavior='monitor-current'>
11+
<span class="text-muted" data-behavior='date'></span> <%= t("current_html", scope: translation_field) %>
12+
</p>
13+
<% end %>
14+
15+
<% if I18n.exists?("completed_html", scope: translation_field) %>
16+
<p data-behavior='monitor-completed'>
17+
<span class="text-muted" data-behavior='date'></span> <%= t("completed_html", scope: translation_field) %>
18+
</p>
19+
<% end %>
20+
21+
<p class="bg-warning" data-behavior='monitor-error' style='display:none;'>
22+
<%= t("error", scope: translation_field) %>
23+
</p>
24+
25+
<div class="progress">
26+
<div class="progress-bar progress-bar-striped active" role="progressbar" aria-valuenow="" aria-valuemin="0" aria-valuemax=""></div>
27+
</div>
28+
</div>
29+
</div>
30+
</div>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# frozen_string_literal: true
2+
3+
module Spotlight
4+
# Renders progress bar html which is updated by progress_monitor.js
5+
class ProgressBarComponent < ViewComponent::Base
6+
attr_reader :exhibit, :translation_field
7+
8+
def initialize(exhibit:, translation_field:)
9+
@exhibit = exhibit
10+
@translation_field = translation_field
11+
super
12+
end
13+
end
14+
end

app/javascript/spotlight/admin/progress_monitor.js

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
1+
import consumer from "../channels/consumer"
2+
13
export default class {
24
connect() {
35
var monitorElements = $('[data-behavior="progress-panel"]');
4-
var defaultRefreshRate = 3000;
56
var panelContainer;
67
var pollers = [];
78

89
$(monitorElements).each(function() {
910
panelContainer = $(this);
1011
panelContainer.hide();
11-
var monitorUrl = panelContainer.data('monitorUrl');
12-
var refreshRate = panelContainer.data('refreshRate') || defaultRefreshRate;
13-
pollers.push(
14-
setInterval(function() {
15-
checkMonitorUrl(monitorUrl);
16-
}, refreshRate)
17-
);
12+
13+
consumer.subscriptions.create({ channel: "ProgressChannel"}, {
14+
received(data) {
15+
if (data.exhibit_id != panelContainer.data('exhibit-id')) return;
16+
updateMonitorPanel(data);
17+
}
18+
});
1819
});
1920

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

30-
function checkMonitorUrl(url) {
31-
$.ajax(url).done(success).fail(fail);
32-
}
33-
34-
function success(data) {
35-
if (data.recently_in_progress) {
36-
updateMonitorPanel(data);
37-
monitorPanel().show();
38-
} else {
39-
monitorPanel().hide();
40-
}
41-
}
42-
43-
function fail() { monitorPanel().hide(); }
44-
4531
function updateMonitorPanel(data) {
4632
panelStartDate().text(data.started_at);
4733
panelCurrentDate().text(data.updated_at);
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Action Cable provides the framework to deal with WebSockets in Rails.
2+
// You can generate new channels where WebSocket features live using the `bin/rails generate channel` command.
3+
4+
import { createConsumer } from "@rails/actioncable"
5+
6+
export default createConsumer()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// Import all the channels to be used by Action Cable

app/jobs/spotlight/process_bulk_updates_csv_job.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,25 @@ def perform(exhibit, bulk_update)
1313
errors = 0
1414
header_converter = ->(header) { header } # Use raw header for columns (since they are configured)
1515
csv_path = bulk_update.file.current_path
16+
started_at = Time.zone.now
17+
1618
File.open(csv_path) do |f|
1719
progress&.total = f.each_line.count(&:present?) - 1 # ignore the header
1820

1921
::CSV.table(f, header_converters: header_converter).each do |row|
2022
process_row(exhibit, row)
2123
progress&.increment
24+
ActionCable.server.broadcast 'progress_channel',
25+
{ exhibit_id: exhibit.id, finished: progress.progress == progress.total,
26+
completed: progress.progress, total: progress.total, errors: errors,
27+
updated_at: Time.zone.now, started_at: started_at }
2228
rescue StandardError => e
2329
job_tracker.append_log_entry(type: :error, exhibit: exhibit, message: e.to_s)
2430
errors += 1
31+
ActionCable.server.broadcast 'progress_channel',
32+
{ exhibit_id: exhibit.id, finished: progress.progress == progress.total,
33+
completed: progress.progress, total: progress.total, errors: errors,
34+
updated_at: Time.zone.now, started_at: started_at }
2535
mark_job_as_failed!
2636
end
2737

app/jobs/spotlight/reindex_job.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,22 @@ def perform(exhibit_or_resources, start: nil, finish: nil, **)
3838
errors += 1
3939
end
4040

41+
started_at = Time.zone.now
42+
4143
resource_list(exhibit_or_resources, start: start, finish: finish).each do |resource|
4244
resource.reindex(touch: false, commit: false, job_tracker: job_tracker, additional_data: job_data, on_error: error_handler) do |*|
4345
progress&.increment
46+
ActionCable.server.broadcast 'progress_channel',
47+
{ exhibit_id: resource.exhibit_id, finished: progress.progress == progress.total,
48+
completed: progress.progress, total: progress.total, errors: errors,
49+
updated_at: Time.zone.now, started_at: started_at, other: resource }
4450
end
4551
rescue StandardError => e
4652
error_handler.call(Struct.new(:source).new(resource), e, nil)
53+
ActionCable.server.broadcast 'progress_channel',
54+
{ exhibit_id: resource.exhibit_id, finished: progress.progress == progress.total,
55+
completed: progress.progress, total: progress.total, errors: errors,
56+
updated_at: Time.zone.now, started_at: started_at, other: resource }
4757
end
4858

4959
job_tracker.append_log_entry(

app/views/spotlight/bulk_updates/_progress_panel.html.erb

Lines changed: 0 additions & 19 deletions
This file was deleted.

app/views/spotlight/bulk_updates/edit.html.erb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44

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

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

119
<div role="tabpanel">
1210
<ul class="nav nav-tabs" role="tablist">

app/views/spotlight/catalog/_admin_header.html.erb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
<% if can? :manage, Spotlight::Resource.new(exhibit: current_exhibit) %>
2-
<div data-behavior='progress-panel' data-monitor-url="<%= monitor_exhibit_resources_path(current_exhibit) %>">
3-
<%= render 'reindex_progress_panel' %>
4-
</div>
2+
<%= render Spotlight::ProgressBarComponent.new(exhibit: current_exhibit, translation_field: 'spotlight.catalog.reindex_progress_panel') %>
53
<div class="add-items-nav clearfix">
64
<div class="float-right float-end">
75
<%= link_to t('.reindex'), reindex_all_exhibit_resources_path(current_exhibit),

app/views/spotlight/catalog/_reindex_progress_panel.html.erb

Lines changed: 0 additions & 19 deletions
This file was deleted.

config/cable.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
development:
2+
adapter: async
3+
4+
production:
5+
adapter: redis
6+
url: redis://localhost:6379/1
7+
channel_prefix: myapp_production

0 commit comments

Comments
 (0)