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

Throttle the image request queue while the map is moving to improve performance #2097

Merged
merged 41 commits into from
Feb 2, 2023

Conversation

zhangyiatmicrosoft
Copy link
Contributor

@zhangyiatmicrosoft zhangyiatmicrosoft commented Jan 25, 2023

Launch Checklist

This is the same as #1856 which will be abandoned by AdamS108.
Need transfer the ownership over to me.

  • Confirm your changes do not include backports from Mapbox projects (unless with compliant license) - if you are not sure about this, please ask!
  • Briefly describe the changes in this PR.
  • Link to related issues.
  • Include before/after visuals or gifs if this PR includes visual changes.
  • Write tests for all new functionality.
  • Document any changes to public APIs.
  • Post benchmark scores.
  • Add an entry to CHANGELOG.md under the ## main section.

Adam Szofran and others added 30 commits November 16, 2022 15:57
…erformance

The image request queue can cause frame rate glitches while the map is moving. To mitigate this, allow the map renderer to throttle the amount of requests processed by the image request queue until the map stops moving again.
…age-request-queue

Users/adam szofran msft/throttle image request queue
@smellyshovel
Copy link
Contributor

@smellyshovel @zhangyiatmicrosoft is there a good way to solve this conflict? Will the split of the #2038 PR allow this to be merged in between the small PRs? Generally speaking, both PRs are in final implantation stages, but both need additional PRs to be fully complete (moving the queue to a different file in this PR and the split to smaller PRs in the other) If you guys want to review each other's code that can be helpful too.

Merge this one as it's ready. I think it's gonna be a long time until get to getImage in my PRs, so by the time I actually do, I will simply try to include the changes from here into my PR.

@zhangyiatmicrosoft
Copy link
Contributor Author

zhangyiatmicrosoft commented Jan 30, 2023

@HarelM consolidating all comments from the previous PR to keep us on the same page:

  1. this.throttleControlCallbackHandleCounter++;
    Q: Can this reach a number too big to become negative?
    A: I don't think so. The design of this counter is to keep track of downstream consumers of ImageRequestQueue per session. It is practically impossible for the number to go beyond 2B.
    HOWEVER, I did notice a bug when it comes to removeThrottleControlCallback, in that it was using splice and changed the index.
    Will be fixed in next iteration.

  2. Two places need strong type: will fix

  3. "queue item knows about the queue"
    I agree this is wrong and will fix.

  4. Regarding the confusing usage of "this":
    When rewind a little bit, I see class ImageRequestQueue is (and will always) be used as singleton and start to doubt why "class" is needed to begin with.
    It was created based on your comment at Dev 22: "This file has all kind of variables laying around, any chance you can turn it into a class?"
    While class nicely wraps things together, it introduces keyword "this" problem and does not minimize well.
    Therefore, my proposal is change to "namespace ImageRequestQueue", removing the class.
    Still wraps things nicely, with smaller runtime script, and avoid "this" keyword.
    What do you think?

@HarelM
Copy link
Collaborator

HarelM commented Jan 30, 2023

Regarding 4 - the problem is not the usage of "this" it's the circular dependency. You should be able to write it down using a class or not, but I want this logic to be encapsulated nicely.

zhangyiatmicrosoft and others added 5 commits February 1, 2023 10:32
* Remove unused tile request cache (maplibre#2101)

* Remove unused tile request cache

* Remove the public method to clear the storage

* Get rid of tile request cache's usages

* merge 2101

* Combine `ResourceType` interface and const into a single enum (maplibre#2103)

* Combine ResourceType interface and const into a single enum

Move it from ajax.ts to request_manager.ts

* Re-run render tests

* Assign strting values to the enum

* Revert changes to tests

* Fix typo

* Don't use MapLibre prefix; use const enum

* Fix "npm run test-build" on Windows (maplibre#2106)

* wip

* fixed path

* rename var

* remove timeout

* add type and use namespace

* test passed

* refactored and cleaned

* min test

* all working

* restore min test

* clean up the cancel function

---------

Co-authored-by: Matthew Mamonov <g.smellyshovel@gmail.com>
…ft/my-maplibre-gl-js into merge-img-req-q

# Conflicts:
#	src/source/vector_tile_source.ts
#	src/util/ajax.ts
# Conflicts:
#	src/source/image_source.ts
#	src/source/raster_dem_tile_source.ts
#	src/source/raster_tile_source.ts
#	src/style/load_sprite.ts
#	src/ui/map.ts
@zhangyiatmicrosoft
Copy link
Contributor Author

zhangyiatmicrosoft commented Feb 1, 2023

New iteration, let’s start from the previous toipics

  1. fixed
  2. a new type “ImageRequestQueueItem”
  3. "queue item knows about the queue"
    The original code was somewhat in this style. The queue is self-driven, meaning as soon as one requested item is processed, it will move on. For this reason, it auto advances previously at ajas.ts, line 328 (advanceImageRequestQueue).
    It is hard to see and honestly the original code was really difficult to understand as well.

    In AdamS108’s iteration both Queue and Item are classes so it looked bad.
    The real queue data structure is nothing more than an array. No separate class is needed.

    In the latest iteration, “namespace ImageRequest”” wraps everything, and it should be much easier to read.
  4. Fixed

More optimizations:

  • Finally moved to a separate file, so won’t have to deal with merge conflicts on ajax.ts. Everything gets moved around so code diff did not help much anyway.
  • Moved a few definitions around as well.
  • Generic code clean ups and shortened a few function/field names in favor of smaller scripts.
  • Happy to say because of all the above, release script size actually reduced ~800 bytes even though this PR is adding more logic.
  • Added a new file “imageRequest.test.ts”, in which first 211 lines are moved from “ajax.test.ts”, and added seven more UTs to cover everything in the new implementation.

src/ui/map.ts Outdated Show resolved Hide resolved
src/ui/map.ts Outdated Show resolved Hide resolved
src/util/imageRequest.ts Outdated Show resolved Hide resolved
src/util/imageRequest.ts Outdated Show resolved Hide resolved
src/util/imageRequest.ts Outdated Show resolved Hide resolved
src/util/imageRequest.ts Outdated Show resolved Hide resolved
@HarelM
Copy link
Collaborator

HarelM commented Feb 1, 2023

Overall this is alot better.
There are some nested callback hell which I hope @smellyshovel can solve after this gets merged.
I've added some minor comments.
Not sure I fully see the value of a namespace over a class, and since namespaces are not currently in use in this project I'm not sure this is the right place to start...
But overall, very nice work.

@zhangyiatmicrosoft
Copy link
Contributor Author

zhangyiatmicrosoft commented Feb 2, 2023

.... Not sure I fully see the value of a namespace over a class

namespace generates an anonymous wrapper. Equivalent of a class with all static methods, and far more compact when it comes to minimized scripts.
I have seen other projects where "amd" is used in tsconfig which automatically wraps things of each file. It is certainly an option I can explore later for this project as well.
As it is now if not use namespace, everything would be just flat, which is not what you want either based on earlier discussions.

@HarelM
Copy link
Collaborator

HarelM commented Feb 2, 2023

THANKS!

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.

4 participants