mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-01 02:03:22 +00:00
Run reports in background
This commit is contained in:
committed by
Maikel Linke
parent
ced959ad6a
commit
a3ef604797
@@ -22,6 +22,13 @@ module Admin
|
||||
def show
|
||||
@report = report_class.new(spree_current_user, params, render: render_data?)
|
||||
|
||||
@background_reports = OpenFoodNetwork::FeatureToggle
|
||||
.enabled?(:background_reports, spree_current_user)
|
||||
|
||||
if @background_reports && request.post?
|
||||
return background(report_format)
|
||||
end
|
||||
|
||||
if params[:report_format].present?
|
||||
export_report
|
||||
else
|
||||
@@ -34,12 +41,12 @@ module Admin
|
||||
private
|
||||
|
||||
def export_report
|
||||
send_data render_report_as(report_format), filename: report_filename
|
||||
send_data @report.render_as(report_format), filename: report_filename
|
||||
end
|
||||
|
||||
def show_report
|
||||
assign_view_data
|
||||
@table = render_report_as(:html) if render_data?
|
||||
@table = @report.render_as(:html) if render_data?
|
||||
render "show"
|
||||
end
|
||||
|
||||
@@ -56,21 +63,21 @@ module Admin
|
||||
request.post?
|
||||
end
|
||||
|
||||
def render_report_as(format)
|
||||
if OpenFoodNetwork::FeatureToggle.enabled?(:background_reports, spree_current_user)
|
||||
@blob = ReportBlob.create_for_upload_later!(report_filename)
|
||||
ReportJob.perform_later(
|
||||
report_class, spree_current_user, params, format, @blob
|
||||
)
|
||||
Timeout.timeout(max_wait_time) do
|
||||
sleep 1 until @blob.content_stored?
|
||||
end
|
||||
def background(format)
|
||||
@blob = ReportBlob.create_for_upload_later!(report_filename)
|
||||
|
||||
# This result has been rendered by Rails in safe mode already.
|
||||
@blob.result.html_safe # rubocop:disable Rails/OutputSafety
|
||||
else
|
||||
@report.render_as(format)
|
||||
end
|
||||
ReportJob.perform_later(
|
||||
report_class, spree_current_user, params, format, @blob, SessionChannel.for_request(request)
|
||||
)
|
||||
|
||||
render cable_ready: cable_car.
|
||||
inner_html(
|
||||
selector: "#report-table",
|
||||
html: render_to_string(partial: "admin/reports/loading")
|
||||
).scroll_into_view(
|
||||
selector: "#report-table",
|
||||
block: "start"
|
||||
)
|
||||
end
|
||||
|
||||
def render_timeout_error
|
||||
@@ -84,17 +91,5 @@ module Admin
|
||||
end
|
||||
render "show"
|
||||
end
|
||||
|
||||
def max_wait_time
|
||||
# This value is used by rack-timeout and nginx, usually 30 seconds in
|
||||
# staging and production:
|
||||
server_timeout = ENV.fetch("RACK_TIMEOUT_SERVICE_TIMEOUT", "15").to_f
|
||||
|
||||
# Zero disables the timeout:
|
||||
return 0 if server_timeout.zero?
|
||||
|
||||
# We want to time out earlier than nginx:
|
||||
server_timeout - 2.seconds
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,4 +7,11 @@ class ApplicationJob < ActiveJob::Base
|
||||
|
||||
# Most jobs are safe to ignore if the underlying records are no longer available
|
||||
# discard_on ActiveJob::DeserializationError
|
||||
|
||||
private
|
||||
|
||||
def enable_active_storage_urls
|
||||
ActiveStorage::Current.url_options ||=
|
||||
Rails.application.config.action_controller.default_url_options
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,9 +2,14 @@
|
||||
|
||||
# Renders a report and stores it in a given blob.
|
||||
class ReportJob < ApplicationJob
|
||||
include CableReady::Broadcaster
|
||||
delegate :render, to: ActionController::Base
|
||||
|
||||
before_perform :enable_active_storage_urls
|
||||
|
||||
NOTIFICATION_TIME = 5.seconds
|
||||
|
||||
def perform(report_class, user, params, format, blob)
|
||||
def perform(report_class, user, params, format, blob, channel = nil)
|
||||
start_time = Time.zone.now
|
||||
|
||||
report = report_class.new(user, params, render: true)
|
||||
@@ -14,6 +19,8 @@ class ReportJob < ApplicationJob
|
||||
execution_time = Time.zone.now - start_time
|
||||
|
||||
email_result(user, blob) if execution_time > NOTIFICATION_TIME
|
||||
|
||||
broadcast_result(channel, format, blob) if channel
|
||||
end
|
||||
|
||||
def email_result(user, blob)
|
||||
@@ -22,4 +29,17 @@ class ReportJob < ApplicationJob
|
||||
blob: blob,
|
||||
).report_ready.deliver_later
|
||||
end
|
||||
|
||||
def broadcast_result(channel, format, blob)
|
||||
cable_ready[channel].inner_html(
|
||||
selector: "#report-table",
|
||||
html: actioncable_content(format, blob)
|
||||
).broadcast
|
||||
end
|
||||
|
||||
def actioncable_content(format, blob)
|
||||
return blob.result if format.to_sym == :html
|
||||
|
||||
render(partial: "admin/reports/download", locals: { file_url: blob.expiring_service_url })
|
||||
end
|
||||
end
|
||||
|
||||
2
app/views/admin/reports/_download.html.haml
Normal file
2
app/views/admin/reports/_download.html.haml
Normal file
@@ -0,0 +1,2 @@
|
||||
.download
|
||||
= link_to t("admin.reports.download.button"), file_url, target: "_blank", class: "button icon icon-file"
|
||||
2
app/views/admin/reports/_loading.html.haml
Normal file
2
app/views/admin/reports/_loading.html.haml
Normal file
@@ -0,0 +1,2 @@
|
||||
.loading
|
||||
= render partial: "components/admin_spinner"
|
||||
@@ -3,7 +3,9 @@
|
||||
|
||||
- content_for :minimal_js, true if @background_reports
|
||||
|
||||
= form_for @report.search, :url => url_for do |f|
|
||||
- options = @background_reports ? { data: { remote: "true" } } : {}
|
||||
|
||||
= form_for @report.search, { url: url_for }.merge(options) do |f|
|
||||
%fieldset.no-border-bottom.print-hidden
|
||||
%legend{ align: 'center'}= t(:report_filters)
|
||||
= render partial: "admin/reports/filters/#{@report_type}", locals: { f: f }
|
||||
@@ -24,4 +26,6 @@
|
||||
%button.btn-print.icon-print{ onclick: "window.print()"}= t(:report_print)
|
||||
|
||||
= t(@error, link: link_to(t(".report_link_label"), @error_url)) if @error
|
||||
= @table
|
||||
|
||||
#report-table
|
||||
= @table
|
||||
|
||||
@@ -60,3 +60,24 @@ table.report__table {
|
||||
margin: 0 !important;
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
#report-table {
|
||||
margin-bottom: 4em;
|
||||
|
||||
.loading, .download {
|
||||
text-align: center;
|
||||
height: 2em;
|
||||
padding: 4em;
|
||||
width: 100%;
|
||||
|
||||
.spinner {
|
||||
font-size: 4em;
|
||||
color: $spree-blue;
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.button {
|
||||
font-size: 1.25em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1469,6 +1469,8 @@ en:
|
||||
pack_by_customer: Pack By Customer
|
||||
pack_by_supplier: Pack By Supplier
|
||||
pack_by_product: Pack By Product
|
||||
download:
|
||||
button: "Download Report"
|
||||
show:
|
||||
report_taking_longer: >
|
||||
Sorry, this report took too long to process.
|
||||
|
||||
Reference in New Issue
Block a user