area: upload: Fix duplicate validation bypass and thread starvation#6869
area: upload: Fix duplicate validation bypass and thread starvation#6869Lame-Fortuna wants to merge 2 commits into
Conversation
|
@Lame-Fortuna are all these changes absolutely necessary to solve the linked issue? If not, could you please keep the diff minimal, it helps review the changes quickly. Thanks! |
|
Also, could you please add the Before and After screencasts to the PR description? |
|
@RitikaPahwa4444 Well, these changes are necessary for unblocking the thread and triggering checks for duplicates for all images:
The changes in strings.xml and the step_count string were just fixing linting issues and typos. Let me know if you want me to revert those. P.S. Added the screenshots |
Yes please, we can take it up separately 🙂 |
There was a problem hiding this comment.
Pull request overview
This PR targets the upload flow’s duplicate/quality validation reliability during multi-image uploads by reducing IO thread blocking during SHA-1 existence checks and by triggering per-item validation when a ViewPager page becomes visible.
Changes:
- Replaced an RxJava
blockingGet()with coroutineawait()during SHA-1 existence checks to avoid blocking threads. - Extended the media details contract/presenter with
verifyImageQuality(index)and invoked it fromUploadMediaDetailFragment.onBecameVisible(). - Minor contract comment cleanup and added lint suppression around duplicate popup formatting.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| app/src/main/java/fr/free/nrw/commons/utils/CustomSelectorUtils.kt | Switches SHA-1 duplicate lookup from blocking to suspending await. |
| app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaPresenter.kt | Adds verifyImageQuality API and implementation to re-run stored quality checks by index. |
| app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailsContract.kt | Exposes verifyImageQuality(index) on the presenter contract. |
| app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.kt | Triggers validation on page visibility, but also removes step title binding and adds a new lint suppression. |
Comments suppressed due to low confidence (2)
app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.kt:244
initializeFragment()no longer setstvTitle(step count/title), and there doesn’t appear to be any other assignment in this fragment. This likely removes the step indicator from the UI. Please restore settingtvTitle(and fix the underlying string formatting issue in resources if that’s why it was removed).
internal fun initializeFragment() {
if (_binding == null) {
return
}
binding.tooltip.setOnClickListener {
showInfoAlert(
R.string.media_detail_step_title,
R.string.media_details_tooltip
)
}
app/src/main/java/fr/free/nrw/commons/utils/CustomSelectorUtils.kt:96
- Now that this uses
await(), coroutine cancellation will throwCancellationException, which is currently caught by the broadcatch (e: Exception)and converted intoImageLoader.Result.ERROR. That can break structured cancellation and lead to work continuing after the calling coroutine is cancelled. Consider rethrowingCancellationException(or catching it separately) and only mapping non-cancellation failures toERROR.
} catch (e: Exception) {
if (e is UnknownHostException) {
Timber.e(e, "Network Connection Error")
}
result = ImageLoader.Result.ERROR
e.printStackTrace()
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
9ee040f to
578c9ca
Compare
|
@RitikaPahwa4444 Reverted those unnecessary changes and applied those Copilot suggestions. |
a07b071 to
0650237
Compare
* Replaced synchronous .blockingGet() with .await() in CustomSelectorUtils.kt to prevent IO dispatcher starvation. * Overloaded checkImageQuality in UploadMediaDetailsContract and Presenter to allow single-parameter (index) validation without breaking existing call sites. * Triggered image verification in UploadMediaDetailFragment's onBecameVisible to ensure validation fires on ViewPager swipe. Fixes commons-app#6401
0650237 to
28ab24a
Compare
|
@Lame-Fortuna do you have any performance improvements stats or profiling data for the the thread starvation that you've fixed for the custom selector? The linked issue is for the normal selector, I tested it out and it works great :) I'll have to test it out for the custom selector, are there any steps I could follow in case there's visible improvement? |
|
✅ Generated APK variants! |
|
@RitikaPahwa4444 No, I do not have exact performance stats or profiling data. The change was a preventative fix, swapping .blockingGet() for .await() stops the underlying IO thread from freezing during concurrent SHA-1 network lookups and allows the coroutine to suspend properly in the Custom Selector. If needed, testing it by selecting a large batch of images should feel noticeably more responsive. However, there is still the issue with delayed popups (duplicate warnings sometimes arriving late via the network and stacking). I left that specific sync/race condition out of scope of this PR, as that requires digging deeper. |
Description
Fixes #6401
Duplicate validation was silently failing on fresh multi-uploads. The ViewPager was skipping per-image checks, and concurrent SHA-1 lookups were starving the IO thread. This PR ensures images are validated exactly when the user swipes to them.
What changes did you make and why?
.blockingGet()for.await()inCustomSelectorUtils.ktto unblock the coroutine during SHA-1 network lookups.checkImageQualityinUploadMediaDetailsContractandUploadMediaPresenterto allow single-parameter (index) validation without breaking existing call sites.checkImageQualityinonBecameVisible(UploadMediaDetailFragment) so validation fires reliably on each ViewPager swipe.Additional Notes / Out of Scope:
UploadMediaPresenter.presenterCallbackwhile debugging. Leaving it untouched here as it's already tracked in Fix potential Context leak and remove StaticFieldLeak suppression in UploadController #6863.Tests performed (required)
Tested
prodDebugon XI M2101K7BI (API 33).Selected multiple existing Commons images and verified the duplicate popup triggers correctly for each specific image as it becomes visible in the ViewPager.
Screenshots (for UI changes only)




Before
After


