Jobs & Progress bar for XWiki Exports

Hi,

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.

WDYT?

Thanks

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.

Exporter:

@Role
public interface Exporter
{
    void export(List<EntityReference> entitiesToExport, Map<String, Object> parameters, OutputStream output);
}

Another option is to introduce a ExportRequest interface or class instead of entitiesToExport and parameters.

WDYT?

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 :slight_smile:

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?

yes

Related to that topic I created back then a ticket for having a cache of exported document, sounds like it would solve that issue too: Loading...

Note that having a progress would actually solve an issue we have now in that we don’t have a proper reporting of errors during export.

Note that progress was added for the LaTeX export but this brainstorming is to generalize this for all exports.

I’ve created Loading...

@tmortagne @mflorea and all @committers: WDYT?

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,
Marius

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.