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

Feature/fluxc media upload service multiple uploads reattach progress #5780

Conversation

mzorz
Copy link
Contributor

@mzorz mzorz commented Apr 28, 2017

This PR makes the multiupload capabilities of the MediaUploadService reflect on the UI when going out of the Editor and back (and images in a Post are still being uploaded).

TEST A (plain old single file upload):

  1. open the editor for a new post.
  2. upload one file, choosing it from the media picker (select from gallery)
  3. wait till it is finished uploading
  4. the post should be changed and updated in the DB, the image should unblur.
  5. get out of the editor
  6. get back in
  7. the image should load from the web (see how it slowly forms, on Aztec)

TEST B (background upload):

  1. open the editor for a new post.
  2. start uploading one file, choosing it from the media picker (select from gallery)
  3. while it is uploading (you can see the progress bar), just get out of the editor
  4. wait for a minute or so (whatever you think is enough for the upload to complete)
  5. get back in the editor
  6. the image should load from the web (see how it slowly forms, on Aztec)

TEST C (background upload - reattach progress):

  1. open the editor for a new post.
  2. upload one file, choosing it from the media picker (select from gallery)
  3. while it is uploading (you can see the progress bar), just get out of the editor
  4. wait for a few seconds (just enough for the upload to progress a bit more, but not as much as to let it complete).
  5. get back in the editor
  6. the progress bar should update itself to wherever it is it’s being uploaded
  7. wait till it is finished uploading
  8. the post should be changed and updated in the DB, the image should unblur.
  9. get out of the editor
  10. get back in
  11. the image should load from the web (see how it slowly forms, on Aztec)

TEST D (multiple upload):

  1. open the editor for a new post.
  2. upload one file, choosing it from the media picker (select from gallery)
  3. while it is uploading (you can see the progress bar), pick another file to insert
  4. both files should be updating their progress, independently
  5. wait till both finish and both present the same behaviour as per TEST A.

TEST E (background upload - multiple upload):

  1. open the editor for a new post.
  2. upload one file, choosing it from the media picker (select from gallery)
  3. while it is uploading (you can see the progress bar), pick another file to insert
  4. both files should be updating their progress, independently
  5. while they’re still uploading (you can see the progress bar), just get out of the editor
  6. wait for a minute or so (whatever you think is enough for the upload of both files to complete)
  7. get back in the editor
  8. the images should load from the web (see how they slowly form, on Aztec)

TEST F (background upload - multiple upload - reattach progress):

  1. open the editor for a new post.
  2. upload one file, choosing it from the media picker (select from gallery)
  3. while it is uploading (you can see the progress bar), pick another file to insert
  4. both files should be updating their progress, independently
  5. while they’re still uploading (you can see the progress bar), just get out of the editor
  6. wait for a few seconds (just enough for the uploads to progress a bit more, but not as much as to let both complete).
  7. get back in the editor
  8. the progress bar should update itself to wherever it is it’s being uploaded
  9. wait till both are finished uploading (both images unbar)
  10. get out of the editor, then get back in
  11. the images should load from the web (see how they slowly form, on Aztec)

TEST G (multicancel):

  1. open the editor for a new post.
  2. upload one file, choosing it from the media picker (select from gallery)
  3. while it is uploading (you can see the progress bar), pick another file to insert
  4. both files should be updating their progress, independently
  5. while they’re still uploading (you can see the progress bar), pick a third one
  6. cancel the first one
  7. now cancel the second one
  8. the third one should still be uploading
  9. wait till it finishes, and make sure it’s the only one finishing (wait some minutes and check the state is as expected: 2 marked for retry, third one completed).

Known Issues

(Planning to work on these on separate PRs)

Different working copies of PostModel

  • It could happen that 2 images are being uploaded, then both finish practically at the same time, then when we try to modify the post’s content (to replace the local image with the remote one) we:
  1. take the post from the db, where 2 images are local and “uploading”
    2.a) image A gets replaced with the remote one, and this gets saved into the DB
    2.b) image B gets replaced with the remote one, and this gets saved into the DB
    We end up having a post with image A local, and image B remote, because what was saved last is 2.b) with a copy of the post that had both local images only.

How to solve this?
We need a way to ensure that all images get saved / replacing the post content.
Fortunately, the service runs as long as there’s stuff enqueued for upload.

  • In the MediaUploadService, what I’m going to do now is wait for all images in the queue (for a given post) to complete, and only then a) get a copy of the post’s content and b) make all replacements at once, then save.

See #5858

Random issues / enhancements

                ProfilingUtils.split("EditorFragment.onDomLoaded completed");
                ProfilingUtils.dump();
                ProfilingUtils.stop();

(see #5860)

cc @aforcier

mzorz added 24 commits April 7, 2017 15:32
…to feature/fluxc-media-upload-service-multiple-uploads-reattach-progress
…nt or after view created for new posts - also clearing failed media ids from local array
…Content() then updating it in onMediaUploadProgress()
…to feature/fluxc-media-upload-service-multiple-uploads-reattach-progress
…, to make upload progress visibility show accordingly
…, and passing the new post contents as a return value in the static method implementation in AztecEditorFragment
…g the list so we are sure to re-load posts once media are uploaded there
@aforcier aforcier self-assigned this May 1, 2017
@@ -3,8 +3,8 @@
import org.wordpress.android.util.helpers.MediaFile;

public interface EditorMediaUploadListener {
void onMediaUploadSucceeded(String localId, MediaFile mediaFile);
void onMediaUploadSucceeded(String localId, EditorFragmentAbstract.MediaType mediaType, MediaFile mediaFile);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding an extra param here for the MediaType seems redundant since we're already getting that from the MediaFile, which we're also sending.

Could we make getEditorMimeType() a (static) method of EditorFragmentAbstract instead, and use that from AztecEditorFragment and from EditPostActivity? Then we can drop this parameter (we'll still need it in onMediaUploadFailed below though, I guess).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in 4417a4c

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(and thank you! nice improvement there)

FluxCUtils.mediaFileFromMediaModel(media));
}
removeMediaFromPendingList(media);
}

private EditorFragmentAbstract.MediaType getEditorMimeType(boolean isVideo) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems a bit weird to keep calling getEditorMimeType(mediaFile.getVideo() - it seems more natural to me to have getEditorMimeType(mediaFile), since that's what we're really doing (getting the media type of the media file).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in 4417a4c

@daniloercoli
Copy link
Contributor

daniloercoli commented May 5, 2017

I tested a variant of TEST B (background upload):

  • open the editor for a new post
  • start uploading one file, choosing it from the media picker (select from gallery)
  • while it is uploading (you can see the progress bar), just get out of the editor
  • get out of the app. send it background
  • wait for a minute or so (whatever you think is enough for the upload to complete)
  • get back in the editor

*The picture appears in the failed mode.

device-2017-05-05-125832

Here is the log:

05-05 12:55:31.689 32488-11155/org.wordpress.android D/WordPress-API: Dispatching action: MediaAction-UPLOADED_MEDIA
05-05 12:55:31.712 32488-32488/org.wordpress.android D/WordPress-MEDIA: 63 - progressing 0.8870163
05-05 12:55:32.775 32488-11155/org.wordpress.android D/WordPress-API: Dispatching action: MediaAction-UPLOADED_MEDIA
05-05 12:55:32.793 32488-32488/org.wordpress.android D/WordPress-MEDIA: 63 - progressing 0.92875826
05-05 12:55:33.864 32488-11155/org.wordpress.android D/WordPress-API: Dispatching action: MediaAction-UPLOADED_MEDIA
05-05 12:55:33.889 32488-32488/org.wordpress.android D/WordPress-MEDIA: 63 - progressing 0.96528244
05-05 12:55:39.227 32488-11155/org.wordpress.android D/WordPress-MEDIA: media upload successful: Response{protocol=h2, code=200, message=, url=https://public-api.wordpress.com/rest/v1.1/sites/15592836/media/new/}
05-05 12:55:39.256 32488-11155/org.wordpress.android D/WordPress-API: Dispatching action: MediaAction-UPLOADED_MEDIA
05-05 12:55:39.260 32488-11155/org.wordpress.android D/WordPress-MEDIA: mediaRestClient: removed id: 63 from current uploads, remaining: 0
05-05 12:55:39.312 32488-32488/org.wordpress.android I/WordPress-MEDIA: Upload completed - localId=63 title=wp-1493895980036
05-05 12:55:39.314 32488-32488/org.wordpress.android D/WordPress-API: Dispatching action: PostAction-UPDATE_POST
05-05 12:55:39.333 32488-7278/org.wordpress.android D/EventBus: No subscribers registered for event class org.wordpress.android.fluxc.store.PostStore$OnPostChanged
05-05 12:55:39.333 32488-7278/org.wordpress.android D/EventBus: No subscribers registered for event class org.greenrobot.eventbus.NoSubscriberEvent
05-05 12:55:39.354 32488-32488/org.wordpress.android V/WordPress-MEDIA: No more media items to upload. Skipping this request - MediaUploadService.
05-05 12:55:39.355 32488-32488/org.wordpress.android I/WordPress-MEDIA: Media Upload Service > completed
05-05 12:55:39.355 32488-32488/org.wordpress.android I/WordPress-MEDIA: No more items pending in queue. Stopping MediaUploadService.
05-05 12:55:39.356 32488-32488/org.wordpress.android I/WordPress-MEDIA: Media Upload Service > destroyed

@aforcier
Copy link
Contributor

aforcier commented May 5, 2017

Confirming what @daniloercoli is seeing - though only if I enable 'Don't keep activities'.

(You're using the visual editor in that screenshot btw @daniloercoli - this branch doesn't have async support for the visual editor, only Aztec.)

@@ -2440,6 +2448,7 @@ public void onMediaUploaded(MediaStore.OnMediaUploaded event) {
onUploadSuccess(event.media);
}
else {
AppLog.w(AppLog.T.MEDIA, "EDITPOSTACTIVITY: " + event.media.getId() + " - " + event.progress);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be a warning-level log. Also, is this log really necessary? We already generate quite a bit of logging per upload, with this there are three logs per tick:

05-05 08:27:02.034 31057-12701/org.wordpress.android.beta D/WordPress-API: Dispatching action: MediaAction-UPLOADED_MEDIA
05-05 08:27:02.082 31057-31057/org.wordpress.android.beta W/WordPress-MEDIA: EDITPOSTACTIVITY: 65 - 0.9653928
05-05 08:27:02.093 31057-31057/org.wordpress.android.beta D/WordPress-MEDIA: 65 - progressing 0.9653928

If they're helpful while working on async we could keep them but keep track that we should reduce them later - these logs make it into helpshift reports, and I think there's a size limit that can prevent earlier useful logs from being preserved.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! was just added to guide my own work, ditched it in 0cd3bc9

@daniloercoli
Copy link
Contributor

(You're using the visual editor in that screenshot btw @daniloercoli - this branch doesn't have async support for the visual editor, only Aztec.)

Right! I'm using the old visual editor.

@daniloercoli
Copy link
Contributor

daniloercoli commented May 5, 2017

though only if I enable 'Don't keep activities turned on'.

That's weird. My devices are experiencing some weird issues today due to activities that are not kept. Also, I don't have 'Don't keep activities turned on'. enabled on them.

I think we should move much of the code outside the activity, since adding images to the editor could consume a lot of memory, (not counting when the user has enabled the resize pictures options, and backgrounding the app could lead the system to dispose the activity....

Note: I would encourage to not test the app on emulator or Nexus 6P ;) We should try to test media related improvements on less powerful devices.

@aforcier
Copy link
Contributor

aforcier commented May 9, 2017

@daniloercoli summarizing the findings from the issue you ran into and what Mario and I discussed:

  1. In general, your steps (start upload, leave editor, background app, wait until media uploads, open post again) should work in this branch with Aztec enabled
  2. Your steps will fail in this branch for the visual editor, because updating posts from outside the visual editor isn't supported. However, they should work in my async visual editor PR: Media Async: Visual editor support #5833

At one point I misunderstood your steps, and looked at exiting the editor while media was uploading (rather than leaving the editor). Trying this again now I realize there is a bug there:

  1. Enable 'don't keep activities'
  2. Start new post, upload media
  3. While media is uploading, background the app (don't leave the editor)
  4. Wait for upload to complete
  5. The post is updated using the async static method @mzorz added in an earlier PR (this will work in the visual editor too with Media Async: Visual editor support #5833)
  6. Re-open the app
  7. The editor is recreated, but uses the PostModel it saved in onSaveInstanceState(), which doesn't have the remote media URL

We should change EditPostActivity to try and fetch the latest copy from the PostStore if it's restoring a post from saved state. I'll open a separate issue for this. Filed in #5863.

@daniloercoli could you confirm that you don't have any issues in this branch if you use Aztec and exit the editor before backgrounding the app?

@daniloercoli
Copy link
Contributor

@daniloercoli could you confirm that you don't have any issues in this branch if you use Aztec and exit the editor before backgrounding the app?

Right! everything is working as expected when I use Aztec.

@aforcier aforcier added the Media label May 10, 2017
@@ -252,7 +252,7 @@ public void run() {
while (count < 1.1) {
sleep(500);

((EditorMediaUploadListener) mEditorFragment).onMediaUploadProgress(mediaId, count);
((EditorMediaUploadListener) mEditorFragment).onMediaUploadProgress(mediaId, false, count);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't look like the false param should be here anymore (onMediaUploadProgress wasn't changed) - also in two more places in this class.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correct - addressed in fd1e412

for (Attributes attrs : content.getAllElementAttributes(uploadingPredicate)) {
String localMediaId = attrs.getValue("data-wpid");
if (!TextUtils.isEmpty(localMediaId)) {
mUploadingMediaProgressMax.put(localMediaId, new Float(0));
Copy link
Contributor

@aforcier aforcier May 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can drop an unnecessary boxing here and make a tiny optimization by just using 0f instead of new Float(0) (also clears a lint warning).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks - addressed in 4606f08

content.refreshText();

mUploadingMedia.put(localMediaId, MediaType.IMAGE);
mUploadingMediaProgressMax.put(localMediaId, new Float(0));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above comment, can use 0f here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in 4606f08

@@ -971,7 +1042,7 @@ public void onClick(DialogInterface dialog, int id) {
// TODO: unmark video failed
}
mFailedMediaIds.remove(localMediaId);
mUploadingMedia.put(localMediaId, mediaType);
mUploadingMediaProgressMax.put(localMediaId, new Float(0));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above comment, can use 0f here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in 4606f08

content.refreshText();

// first obtain the latest maximum
float maxProgressForLocalMediaId = mUploadingMediaProgressMax.get(localMediaId);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can throw an NPE if the localMediaId doesn't exist in mUploadingMediaProgressMax (HashMap.get() will return a null Float, which will crash when unboxing into a float).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome catch - addressed in 1102c4f

@aforcier
Copy link
Contributor

Alright @mzorz, did another full pass and went through all your cases. Left a few small comments for things I missed earlier - should be good to go after those are fixed 👍

@mzorz
Copy link
Contributor Author

mzorz commented May 10, 2017

ok! ready again @aforcier 🙇

@aforcier
Copy link
Contributor

:shipit: Nice work @mzorz!

@aforcier aforcier merged commit 70483ab into feature/fluxc-media-upload-service-multiple-uploads May 10, 2017
@aforcier aforcier deleted the feature/fluxc-media-upload-service-multiple-uploads-reattach-progress branch May 10, 2017 15:33
@mzorz mzorz mentioned this pull request Jan 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants