Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only start uploader when all files have been setup #85

Merged
merged 1 commit into from
Nov 23, 2016

Conversation

LevelbossMike
Copy link
Contributor

Fixes #84

When uploading muliple files which upload-setup depended on an
async operation (e.g. when obtaining the upload url from a
backend-api) the uploader component contained a race condition
where it assumed that the first file in the plupload uploader
FilesAdded callback would also be the first to start uploading.

If that wasn't the case and due to the async nature of obtaining
relevant upload-information one of the files that was queued for
a later upload in plupload was to call its file#upload-method
first the upload of the first file in the queue would fail as it
hadn't completed its setup completely yet.

By making sure that the uploader will only start when all of the
files that should be uploaded have been setup correctly we make
sure that this race condition is no longer an issue.

Fixes knownasilya#84

When uploading muliple files which upload-setup depended on an
async operation (e.g. when obtaining the upload url from a
backend-api) the uploader component contained a race condition
where it assumed that the first file in the plupload uploader
`FilesAdded` callback would also be the first to start uploading.

If that wasn't the case and due to the async nature of obtaining
relevant upload-information one of the files that was queued for
a later upload in plupload was to call its file#upload-method
first the upload of the first file in the queue would fail as it
hadn't completed its setup completely yet.

By making sure that the uploader will only start when all of the
files that should be uploaded have been setup correctly we make
sure that this race condition is no longer an issue.
@LevelbossMike
Copy link
Contributor Author

LevelbossMike commented Nov 22, 2016

I'm not sure why the build is failing but it seems it has been failing for some time now for beta and canary.

The issue can be reproduced by adding an artificial delay before calling the file#upload method triggered by the onfileadd-action. This of course would happen quite frequently when dealing with real network requests because we can't be sure in which order responses arrive after we send out some async requests.

So given the example from #84 and making sure via a delay that the second File that proxies the second PluploaderFile that should be uploaded when uploading multiple files will likely call its File#upload method before the File that proxies the first pluploaderFile object in the plupload-uploader queue will call its File#upload-method this can be reproduced.

<div class="component-that-wraps-pl-uploader">
  {{#pl-uploader multiple=true onfileadd="uploadImage" as |queue dropzone|}}
    {{yield queue dropzone}}
  {{/pl-uploader}}
</div>
// custom component
var delay = 500;
export default Ember.Component.extend({
  // ...
  actions: {
    uploadImage(file) {
      return somePromiseChain
        .then(function(modelThatContainsUploadUrl) {
          return new Ember.RSVP.Promise(function(resolve, reject) {
            Ember.run.later(resolve.bind(null, modelThatContainsUploadUrl), delay);
             delay = delay - 100;
          });
        })
        .then(function(modelThatContainsUploadUrl) {
          const {url, opts} = modelThatContainsUploadUrl.getProperties('url', 'opts');
          return file.upload(url, {data: opts});
        });
    }
  }
});

The problem here is that uploader#start will try to upload files in the order it has queued them initially and the files that come first in this queue do not necessarily have run the part of File#upload that syncs settings https://github.com/tim-evans/ember-plupload/blob/5646965e40d0e468aa3ad08dcfddf2c5a07ad4fd/addon/system/file.js#L152

@tim-evans
Copy link
Collaborator

This looks good! It fails on beta / canary anyways. I'll get those fixed when it comes to a head. Thanks for digging in. 👍

@LevelbossMike
Copy link
Contributor Author

LevelbossMike commented Nov 23, 2016

When everything looks good can we merge this in? Would be great if we didn't need to point to a fork in package.json. Or do you want me to improve anything in this pr? 🍻

@tim-evans tim-evans merged commit 6581fb6 into knownasilya:master Nov 23, 2016
@tim-evans
Copy link
Collaborator

Done! I can release after the holidays

@LevelbossMike
Copy link
Contributor Author

Cool! thx a lot!

@tim-evans
Copy link
Collaborator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants