NOTE: This page describes an Orbeon Forms project, not a feature which is currently part of Orbeon Forms. As of 2011-09, phase 1 and phase 2 of this improvement are complete, and phase 3 is almost complete.
December 2010 planPhase 1Phase 1 is completed.
2011-01-04 Status update: upload queue functional, indicator for upload, new xxforms-upload-start The upload queue is now functional: when users select a file A, the upload of A starts right away; if during the upload, through another upload control, users select a file B, the upload of B will start as soon as uploading A is finished. While files are uploaded, Ajax requests can happen in parallel, so users can continue to interact with the form.How should uploads impact the display of the regular loading indicator? One approach is to show the loading indicator if there is an Ajax request or a upload in progress. With this approach, while long-running uploads happen in the background, the loading indicator is displayed for prolonged periods of time, and there is no way for users to know if the page is waiting to be refreshed after an action they took that results in an Ajax request. Since the loading indicator will have its own progress indicator, it will be clear enough that an upload is in progress, and we resolved to keep the loading indicator only for Ajax requests and page replacements. For now, we don't have a real progress bar, but as soon as the upload starts, the file selection control is replaced by a spinner (animated GIF set from CSS); this prevents users from selecting another file until the upload is finished (fully uploaded or canceled), and informs users that the upload is in progress. This concludes phase 1 of the upload implementation. The next step is to allow users to cancel an upload currently in progress (part of phase 2), and next to show a proper progress indicator, not just just an indicator that an upload is currently happening (part of phase 3). Phase 2
2011-01-05 Status update: cancel implemented, change of implementation, thinking of progress The ability for users to cancel uploads is now implemented. While the upload is in progress, a "Cancel" link is shown next to the spinning icon indicating that an upload is in progress. It works quite well, with one caveat. The upload starts in the background right after a file is selected. So imagine that you have a form with multiple upload fields: select a file in A, and that file uploads. If you hit cancel, then this upload is cancelled. Good. Now while A is uploaded, select files in B and C. Those are added to the upload queue, and will be sent as soon we're done uploading A. OK, now A is finished, and B+C are sent. What happens if users cancel B? In the current implementation, since B and C are sent together, we are "smart" and cancel both B and C. Logical? Yes. Expected? Mmmh… not sure.Even if uploading B+C in one shot seemed like a good idea, we're going to change this and really upload just one file at a time (B, then C). Uploading one file at a time will also help with the implementation of the progress bar. The files are sent in the body of a multipart/form-data POST. So the body starts with something like: Content-Type: multipart/form-data; boundary=---------------------------241791819029657Content-Length: 3956246We have here the total size of whatever is sent. If B+C were sent, the server would be unable to tell what the progress of B or C is independently of each other. 2011-01-05 Status update: uploading file by file, next: progress indicator The plan outlined yesterday, where we upload files one by one to make the cancel behavior more user-friendly (i.e. correct!), and facilitate the implementation of a progress bar is now implemented. Next, we want to implement the progress bar. Since we only have one upload per page (i.e. per UUID), the client can just ask the server what the current progress is. We can reuse the <xxforms:event> element here, and specify a source-control-id to be coherent with the way it is used in other places, all the server cares is that it is asked for the progress update for a certain UUID.<xxforms:event-request xmlns:xxforms="http://orbeon.org/oxf/xml/xforms"> <xxforms:uuid>797C7ABC-226E-3C42-0BE8-F4966C37E404</xxforms:uuid> <xxforms:sequence>6</xxforms:sequence> <xxforms:action> <xxforms:event name="xxforms-upload-progress" source-control-id="my-upload"/> </xxforms:action></xxforms:event-request>In the server response, the control id from the request is repeated, just for consistency. (Again, the upload progress is not tied to a control on the server, but only to the UUID.) (An Ajax request will contain at most one query for the upload progress, but it can contain other events as well.) The server tells the client the total number of bytes it expects (from the Content-Length in the POST body), and how many it received so far. The sizes won't exactly correspond to the size of the file, as the POST body contains additional information, but this is enough for the client to show a progress in percent, and maybe also good enough to show a size rounded in KB. If the server doesn't yet know the progress is, because it hasn't processed the Content-Length in the request body yet, it can just ignore the upload progress query; the client will ask again later.<xxf:event-response xmlns:xxf="http://orbeon.org/oxf/xml/xforms"> <xxf:action> <xxf:control-values> <xxf:control id="my-upload" progress-received="1249129" progress-expected="3954614"/> </xxf:control-values> </xxf:action></xxf:event-response>Another topic is the proper handling of interrupted connections. If an Ajax request fails because of a connection problem, we resent it. The same should happen for uploads. For this to work, we need to the YUI Connection Manager to notify us when an upload failed, but at this point it doesn't seem to do so. We are trying to resolve this with the YUI team. 2011-01-19 Erik's note on server-side aspects of progress indicatorCurrently, a file upload sent as multipart/form-data is processed by commons-fileupload as soon as "somebody" (typically oxf:request) asks for request parameters.In order to track progress, we must switch to the fileupload streaming API. This provides a streaming InputStream so we can store progress information as we are reading the stream from the browser. Proposal:
Phase 3
Concurrency issuesThe new architecture allows uploads to go on in the background in parallel with Ajax requests. This can cause issues: replace="all" -> 2 main cases:
Case of replace="instance|none":
Proposal:
Later:
NOTE: XForms 1.1 calls for mode="synchronous|asynchronous".
Additional feature: progress monitoringThis is a feature of its own.
Plan
|

