-
Notifications
You must be signed in to change notification settings - Fork 1.3k
[Merged][core] Deprioritize offline downloads #13019
Conversation
719c4da
to
843b8b5
Compare
include/mbgl/storage/resource.hpp
Outdated
Kind kind; | ||
LoadingMethod loadingMethod; | ||
std::string url; | ||
std::size_t isLowPriority; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using a boolean or enum would better convey the fact that this is a flag, and not a scalar type.
// context: https://github.com/mapbox/mapbox-gl-native/issues/12655 | ||
PendingRequests() : prioritizedPendingRequestsList(2), prioritizedPendingRequestsMap(2) {} | ||
|
||
std::vector<std::list<OnlineFileRequest*>> prioritizedPendingRequestsList; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using std::array<std::list<OnlineFileRequest*>, 2>
conveys the intention better: a std::vector
is resizable and uses dynamically allocated memory, while a std::array
is fixed size and is stored inline.
it = prioritizedPendingRequestsMap[1].find(request); | ||
if (it != prioritizedPendingRequestsMap[1].end()) { | ||
prioritizedPendingRequestsList[1].erase(it->second); | ||
prioritizedPendingRequestsMap[1].erase(it); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To reduce code duplication, you could wrap the list + map together in one class, and handle the prioritization outside of the class.
PendingRequests() : prioritizedPendingRequestsList(2), prioritizedPendingRequestsMap(2) {} | ||
|
||
std::vector<std::list<OnlineFileRequest*>> prioritizedPendingRequestsList; | ||
std::vector<std::unordered_map<OnlineFileRequest*, std::list<OnlineFileRequest*>::iterator>> prioritizedPendingRequestsMap; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original code used a list and a map with request pointer -> list iterator and was added in f5b521f, but I'm not convinced that we need two separate data structures here. Given that the number of requests we have in the queue is usually pretty small (<100), a linear search in the queue might be just as fast and would simplify the logic quite a bit.
else { | ||
assert(num_high_priority_requests <= (int) queue.size()); | ||
auto new_pos = queue.begin(); | ||
for (int i = 0; i < num_high_priority_requests; i++) new_pos++; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of this iterator increment - you could replace num_high_priority_requests
with the iterator to the last inserted high priority request. Regular insertions can then be made without traversing the list. When removing/popping requests, an additional check is needed before the removal/pop to ensure that the lastHighPriorityRequest
iterator points to a valid list entry.
include/mbgl/storage/resource.hpp
Outdated
tileData(std::move(tileData_)) { | ||
} | ||
|
||
void setLowPriority() { isLowPriority = true; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would an enum with regular and low/background be more appropriate here?
ebb0026
to
c2a949c
Compare
Tests pass, I have cleaned up the commit history and it is rebased to current master. @kkaefer or @asheemmamoowala mind taking another look? 🙂 Wrt to the needed changes for setting the number of maximum concurrent requests, I have opened another separate issue here #13130 and was thinking on working on that next as a follow-up issue of this PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approved pending a few nit picks
@@ -169,13 +156,80 @@ class OnlineFileSource::Impl { | |||
networkIsReachableAgain(); | |||
} | |||
|
|||
void setMaximumConcurrentRequestsOverride(const uint32_t maximum_concurrent_requests_override_) { | |||
maximum_concurrent_requests_override = maximum_concurrent_requests_override_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: use camelCase for variable names
void networkIsReachableAgain() { | ||
for (auto& request : allRequests) { | ||
request->networkIsReachableAgain(); | ||
} | ||
} | ||
|
||
|
||
struct PendingRequests { | ||
PendingRequests() : queue(), first_low(queue.begin()) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: nit: use camelCase for variable names. Also expand first_low
to firstLowPriorityRequest
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How are we handling requests that get added to the queue with a low priority, then another request comes in that has standard priority? Are they getting upgraded?
include/mbgl/storage/resource.hpp
Outdated
@@ -24,6 +24,11 @@ class Resource { | |||
Image | |||
}; | |||
|
|||
enum Priority : uint8_t { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use an enum class
here. Ideally the type would be bool
969cd07
to
25f659a
Compare
Changed some small fixups according to the comments 🙂 Gonna merge
Currently, the requests would not be upgraded but appear in the queue twice. If we request a resource As far I understand, there is no deduplication logic in This is something that can be checked before we insert a request in a queue but the benefit is probably not too high to do it now. |
- priorities can be low or regular - offline downloads should have low priority to not throttle "regular requests"
- only process low priority requests (=offline requests) if there are no outstanding regular requests - favour regular requests over low priority ones
- ensure that low priority requests are handled last - add option to set the number of maximum concurrent requests for tests - some style fixups
25f659a
to
eedf8cf
Compare
Working towards targeting #12655:
Current approach:
OnlineFileSource
OfflineDownload
to low prioritybool isLowPriority
flag toResource
Todos:
setLowPriority()
here. Would it be better to set the priority flag via an input parameter in the constructors? Should it be a parameter that defaults to zero? Or would it be better to enforce it being set explicitly?[core]
related work: #12910