I’d like to brainstorm about how we’d implement introducing progress bar for exports. Exports can take a long time depending on the export type and what is exported (exporting a full wiki to HTML for example can take quite long).
These are my current ideas/notes.
Principle:
Progress bars/jobs require client and server code
The server code perform the code to export and notify the Job Progress Manager about the status
The client code displays the progress bar, calls the server code and updates the progress bar
So my idea ATM would be to do the following:
Modify the existing export.vm by introducing a query string param to display progress.
Once the user clicks the “Export” button in the export modal we render this export template (by using the export action as we currently do)
We introduce a new export script service (and a new Export component) in charge of performing the export, in a new xwiki-platform-export module. The export.vm uses this script service to trigger the export.
Once the export is finished, the export.vm displays a link to the export in the UI and the user just have to click on it to get the result.
Note that we don’t need to refactor existing exports immediately since we’d introduce a query string parameter to indicate if the export should be sync or async.
Note that this is not perfect since it means storing the result locally in a temporary location on the server in order to serve it. It’s not great since in the case when the export is fast, it’s less efficient than just returning the streamed data.
Now for fully streamed exports, they can just not use progress bars
So that would mean a new export extension would propose an action link with that query string parameter: something like /export/MyPage/?async=true? So that ExportAction knows it should renders immediately export.vm with the progress bar, or that it should only return the exported document?
Your proposal assumes that the export is performed entirely on the server side, where it can be implemented as a job, which can notify its progress. That’s not the case with the client-side PDF export where half of the work is done server-side (to render and aggregate the HTML) and the other half on the browser (to split the HTML into print pages and print to PDF). Many times, especially for large exports, the second half takes most of the time. Rendering 100 pages server-side is fast, but:
loading the aggregated HTML and the required resources (images, CSS, JavaScript)
waiting for the loaded JavaScript code to be executed (e.g. waiting for the live data widgets to be loaded, diagrams or MathJax equations to be rendered)
splitting the final web page into print pages (using paged.js)
waiting for the browser to generate the PDF
can be very slow. Having a unified progress bar won’t help much because the user will see it frozen at 50% for most of the export.
The same is true if you do the export server-side using a headless Chrome. And in general, any export that calls an external service which takes most of the export time. The progress bar will jump quickly to some level, stay there for the rest of the export, and then jump to 100%.
I’m not saying that showing a progress bar is bad. It’s just that I’m not sure that we can have a generic implementation to be shared by all export types and which provides useful / meaningful progress information.
Thanks for the input. I still believe it’s better than no progress bar. Also, it’s still up to each export implementation to make the bar progress and thus whatever the implementation is (calling some external service, etc), it has to find ways to update the progress as much as it can (calling some async external service if it exists, etc). If it cannot, it cannot and there’ll be a jump but at least there’ll be some progress and logs, which is better than now anyway.