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

Fix annotation update missing issue. #441

Merged
merged 4 commits into from
Jun 29, 2021
Merged

Fix annotation update missing issue. #441

merged 4 commits into from
Jun 29, 2021

Conversation

Chaoba
Copy link
Contributor

@Chaoba Chaoba commented Jun 21, 2021

PRs must be submitted under the terms of our Contributor License Agreement CLA.
Fixes: #433

Pull request checklist:

  • Briefly describe the changes in this PR.
  • Include before/after visuals or gifs if this PR includes visual changes.
  • Write tests for all new functionality. If tests were not written, please explain why.
  • Add example if relevant.
  • Document any changes to public APIs.
  • Apply changelog label ('breaking change', 'bug 🪲', 'build', 'docs', 'feature 🍏', 'performance ⚡', 'testing 💯') or use the label 'skip changelog'
  • Add an entry inside this element for inclusion in the mapbox-maps-android changelog: <changelog>Fix annotation update missing issue</changelog>.

Summary of changes

Some annotation updates could be ignored as we will remove the pending GeojsonSource update in the queue.
This pr remove this logic to guarantee all annotation update could be executed.

User impact (optional)

@Chaoba Chaoba added the bug 🪲 Something isn't working label Jun 21, 2021
@Chaoba Chaoba requested a review from a team June 21, 2021 07:32
@Chaoba Chaoba self-assigned this Jun 21, 2021
Copy link
Contributor

@kiryldz kiryldz left a comment

Choose a reason for hiding this comment

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

@Chaoba I don't think it's a good idea although I understand how this solves a problem.

Root cause of underlying issue is posting updates very frequently. It basically does not make any sense as we can't render let's say 100 times each 1 ms - we depend on vsync updates and render each 16 ms (on most screens).

If we remove the code here like you did - we will have issues in parsing large geojson files. E.g. user has set to parse enormous geojson_1 and while parsing is happening also queued 100 more. There is no sense to parse 99 of them because they will be basically overwritten by the most recent one and if we do not overwrite - it will result in huge delay of showing this geojson data on map.

My proposal here for you case would be introducing handler inside annotation plugin and queue updates there.

@Chaoba
Copy link
Contributor Author

Chaoba commented Jun 21, 2021

@Chaoba I don't think it's a good idea although I understand how this solves a problem.

Root cause of underlying issue is posting updates very frequently. It basically does not make any sense as we can't render let's say 100 times each 1 ms - we depend on vsync updates and render each 16 ms (on most screens).

If we remove the code here like you did - we will have issues in parsing large geojson files. E.g. user has set to parse enormous geojson_1 and while parsing is happening also queued 100 more. There is no sense to parse 99 of them because they will be basically overwritten by the most recent one and if we do not overwrite - it will result in huge delay of showing this geojson data on map.

My proposal here for you case would be introducing handler inside annotation plugin and queue updates there.

The root cause for this issue is that there are too many updates and the most recent update cancels the former update. Simply introducing a handler in the annotation plugin will not resolve this issue, because all the updates in this handler will return immediately as the parse works are handled in the handler of GeojsonSource.
For example, we have handler A in annotation plugin and handler B in GeojsonSource and we have 2 update jobs which will cost some time.
Handler A will process these 2 jobs immediately to push the update to Handler B and in B the first one will be canceled by the second one, the issue still exists.

@kiryldz
Copy link
Contributor

kiryldz commented Jun 21, 2021

@Chaoba I don't think it's a good idea although I understand how this solves a problem.
Root cause of underlying issue is posting updates very frequently. It basically does not make any sense as we can't render let's say 100 times each 1 ms - we depend on vsync updates and render each 16 ms (on most screens).
If we remove the code here like you did - we will have issues in parsing large geojson files. E.g. user has set to parse enormous geojson_1 and while parsing is happening also queued 100 more. There is no sense to parse 99 of them because they will be basically overwritten by the most recent one and if we do not overwrite - it will result in huge delay of showing this geojson data on map.
My proposal here for you case would be introducing handler inside annotation plugin and queue updates there.

The root cause for this issue is that there are too many updates and the most recent update cancels the former update. Simply introducing a handler in the annotation plugin will not resolve this issue, because all the updates in this handler will return immediately as the parse works are handled in the handler of GeojsonSource.
For example, we have handler A in annotation plugin and handler B in GeojsonSource and we have 2 update jobs which will cost some time.
Handler A will process these 2 jobs immediately to push the update to Handler B and in B the first one will be canceled by the second one, the issue still exists.

@Chaoba again, I fully understand your fix. All what I'm saying is that changing that logic in geojson in not correct. Yes, it will fix annotations but this approach is not correct as we apply map updates asap and not queue them up.
I'm looking at code here:

geoJsonSource.featureCollection(FeatureCollection.fromFeatures(features), onDataParsed = {})

Why can't we add that logic here? Not updating next feature until previous one is parsed.

@Chaoba Chaoba requested a review from kiryldz June 21, 2021 13:10
@@ -118,7 +141,7 @@ class PointAnnotationActivity : AppCompatActivity() {
}
// random add symbols across the globe
val pointAnnotationOptionsList: MutableList<PointAnnotationOptions> = ArrayList()
for (i in 0..20) {
for (i in 0..2000) {
Copy link
Contributor

Choose a reason for hiding this comment

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

is it intended to leave this large number here? or were you just testing? 😄
perhaps better having an integration test appying 2000 updates and verifying that all calls where executed (and not were skipped).

private val workerHandler by lazy {
Handler(workerThread.looper)
}
private val mainHandler = Handler(Looper.getMainLooper())
Copy link
Contributor

Choose a reason for hiding this comment

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

btw I guess it could be static, no need to create each time, wdyt?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, this one could be static.

private val workerHandler by lazy {
Handler(workerThread.looper)
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
var workerThread = HandlerThread("STYLE_WORKER").apply {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we revert lazy initialization? That thread in some situations may not even be started (if user does not use geojson source). I'm OK to leave it internal for tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a compromise for tests. With lazy initialization, only the first case will succeed, in the following one, this thread will be in the inactive state.

@Chaoba Chaoba requested review from kiryldz and pengdev June 25, 2021 02:37
@Chaoba Chaoba force-pushed the kl-annotation-update branch 4 times, most recently from a7d0e0e to 36a4dd0 Compare June 29, 2021 02:34
Copy link
Contributor

@kiryldz kiryldz left a comment

Choose a reason for hiding this comment

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

LGTM with couple small questions.

@Chaoba Chaoba merged commit fdc298c into main Jun 29, 2021
@Chaoba Chaoba deleted the kl-annotation-update branch June 29, 2021 13:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🪲 Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Annotation updates are being dropped
3 participants