mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-02 02:11:33 +00:00
Add fallback report loading in case websockets fail
This also resolves a race condition scenario. Even if the report gets rendered via websockets before the controller response is rendered then the fallback script loads the report again. It's not the most beautiful but probably okay until we replace websockts altogether. I'm leaving websockets in at the moment because it can render the report much quicker than polling can.
This commit is contained in:
@@ -58,12 +58,12 @@ module Admin
|
||||
end
|
||||
|
||||
def render_in_background
|
||||
blob = ReportBlob.create_for_upload_later!(report_filename)
|
||||
@blob = ReportBlob.create_for_upload_later!(report_filename)
|
||||
|
||||
ReportJob.perform_later(
|
||||
report_class:, user: spree_current_user, params:,
|
||||
format: report_format,
|
||||
blob:,
|
||||
blob: @blob,
|
||||
channel: ScopedChannel.for_id(params[:uuid]),
|
||||
)
|
||||
end
|
||||
|
||||
44
app/views/admin/reports/_fallback_display.html.haml
Normal file
44
app/views/admin/reports/_fallback_display.html.haml
Normal file
@@ -0,0 +1,44 @@
|
||||
.download.hidden
|
||||
= link_to t("admin.reports.download.button"), file_url, target: "_blank", class: "button icon icon-file"
|
||||
|
||||
:javascript
|
||||
(function () {
|
||||
const tryDownload = function() {
|
||||
const link = document.querySelector(".download a");
|
||||
|
||||
// If the report was already rendered via web sockets:
|
||||
if (link == null) return;
|
||||
|
||||
fetch(link.href).then((response) => {
|
||||
if (response.ok) {
|
||||
response.blob().then((blob) => blob.text()).then((text) => {
|
||||
const loading = document.querySelector(".loading");
|
||||
|
||||
if (loading == null) return;
|
||||
|
||||
loading.remove();
|
||||
document.querySelector("#report-go button").disabled = false;
|
||||
|
||||
if (link.href.endsWith(".html")) {
|
||||
// This replaces the hidden download button with the report:
|
||||
link.parentElement.outerHTML = text;
|
||||
} else {
|
||||
// Or just show the download button when it's ready:
|
||||
document.querySelector(".download").classList.remove("hidden")
|
||||
}
|
||||
});
|
||||
} else {
|
||||
setTimeout(tryDownload, 1000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
A lot of reports are rendered within 250ms. Others take at least
|
||||
2.5 seconds. There's a big gap in between. Observed on:
|
||||
https://openfoodnetwork.org.au/admin/sidekiq/metrics/ReportJob?period=8h
|
||||
https://openfoodnetwork.org.uk/admin/sidekiq/metrics/ReportJob?period=8h
|
||||
https://coopcircuits.fr/admin/sidekiq/metrics/ReportJob?period=8h
|
||||
*/
|
||||
setTimeout(tryDownload, 250);
|
||||
})();
|
||||
@@ -2,4 +2,5 @@
|
||||
= button t(:go), "report__submit-btn", "submit", disabled: true
|
||||
= turbo_stream.update "report-table" do
|
||||
= render "admin/reports/loading"
|
||||
= render "admin/reports/fallback_display", file_url: @blob.expiring_service_url
|
||||
= turbo_stream.scroll_into_view("#report-table", behavior: "smooth")
|
||||
|
||||
@@ -115,8 +115,6 @@ RSpec.describe '
|
||||
end
|
||||
|
||||
it "allows the report to finish before the loading screen is rendered" do
|
||||
pending "Race condition between loading message and report rendering"
|
||||
|
||||
login_as_admin
|
||||
visit admin_report_path(report_type: :customers)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user