Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(152)

Side by Side Diff: content/browser/download/parallel_download_job.cc

Issue 2750853004: Add a delay to send the parallel requests. (Closed)
Patch Set: Work on feedback. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/download/parallel_download_job.h" 5 #include "content/browser/download/parallel_download_job.h"
6 6
7 #include "base/memory/ptr_util.h" 7 #include "base/memory/ptr_util.h"
8 #include "content/browser/download/download_create_info.h" 8 #include "content/browser/download/download_create_info.h"
9 #include "content/browser/download/parallel_download_utils.h" 9 #include "content/browser/download/parallel_download_utils.h"
10 #include "content/public/browser/browser_context.h" 10 #include "content/public/browser/browser_context.h"
11 #include "content/public/browser/storage_partition.h" 11 #include "content/public/browser/storage_partition.h"
12 12
13 namespace content { 13 namespace content {
14 14
15 ParallelDownloadJob::ParallelDownloadJob( 15 ParallelDownloadJob::ParallelDownloadJob(
16 DownloadItemImpl* download_item, 16 DownloadItemImpl* download_item,
17 std::unique_ptr<DownloadRequestHandleInterface> request_handle, 17 std::unique_ptr<DownloadRequestHandleInterface> request_handle,
18 const DownloadCreateInfo& create_info) 18 const DownloadCreateInfo& create_info)
19 : DownloadJobImpl(download_item, std::move(request_handle)), 19 : DownloadJobImpl(download_item, std::move(request_handle)),
20 initial_request_offset_(create_info.save_info->offset), 20 initial_request_offset_(create_info.save_info->offset),
21 initial_request_length_(create_info.save_info->length) {} 21 initial_request_length_(create_info.save_info->length),
22 requests_sent_(false) {}
22 23
23 ParallelDownloadJob::~ParallelDownloadJob() = default; 24 ParallelDownloadJob::~ParallelDownloadJob() = default;
24 25
25 void ParallelDownloadJob::Start() { 26 void ParallelDownloadJob::Start() {
26 DownloadJobImpl::Start(); 27 DownloadJobImpl::Start();
27 28
28 BuildParallelRequests(); 29 BuildParallelRequestAfterDelay();
29 } 30 }
30 31
31 void ParallelDownloadJob::Cancel(bool user_cancel) { 32 void ParallelDownloadJob::Cancel(bool user_cancel) {
32 DownloadJobImpl::Cancel(user_cancel); 33 DownloadJobImpl::Cancel(user_cancel);
34
35 if (!requests_sent_) {
36 timer_.Stop();
37 return;
38 }
39
33 for (auto& worker : workers_) 40 for (auto& worker : workers_)
34 worker->Cancel(); 41 worker->Cancel();
35 } 42 }
36 43
37 void ParallelDownloadJob::Pause() { 44 void ParallelDownloadJob::Pause() {
38 DownloadJobImpl::Pause(); 45 DownloadJobImpl::Pause();
46
47 if (!requests_sent_) {
48 timer_.Stop();
49 return;
50 }
51
39 for (auto& worker : workers_) 52 for (auto& worker : workers_)
40 worker->Pause(); 53 worker->Pause();
41 } 54 }
42 55
43 void ParallelDownloadJob::Resume(bool resume_request) { 56 void ParallelDownloadJob::Resume(bool resume_request) {
44 DownloadJobImpl::Resume(resume_request); 57 DownloadJobImpl::Resume(resume_request);
45 if (!resume_request) 58 if (!resume_request)
46 return; 59 return;
47 60
61 // Send parallel requests if the download is paused previously.
62 if (!requests_sent_) {
63 if (!timer_.IsRunning())
64 BuildParallelRequestAfterDelay();
65 return;
66 }
67
48 for (auto& worker : workers_) 68 for (auto& worker : workers_)
49 worker->Resume(); 69 worker->Resume();
50 } 70 }
51 71
52 void ParallelDownloadJob::ForkRequestsForNewDownload(int64_t bytes_received, 72 void ParallelDownloadJob::ForkRequestsForNewDownload(int64_t bytes_received,
53 int64_t total_bytes, 73 int64_t total_bytes,
54 int request_count) { 74 int request_count) {
55 if (!download_item_ || total_bytes <= 0 || bytes_received >= total_bytes || 75 if (!download_item_ || total_bytes <= 0 || bytes_received >= total_bytes ||
56 request_count <= 1) { 76 request_count <= 1) {
57 return; 77 return;
58 } 78 }
59 79
60 int64_t bytes_left = total_bytes - bytes_received; 80 int64_t bytes_left = total_bytes - bytes_received;
61 int64_t slice_size = bytes_left / request_count; 81 int64_t slice_size = bytes_left / request_count;
62 slice_size = slice_size > 0 ? slice_size : 1; 82 slice_size = slice_size > 0 ? slice_size : 1;
63 int num_requests = bytes_left / slice_size; 83 int num_requests = bytes_left / slice_size;
64 int64_t current_offset = bytes_received + slice_size; 84 int64_t current_offset = bytes_received + slice_size;
65 85
66 // TODO(xingliu): Add records for slices in history db. 86 // TODO(xingliu): Add records for slices in history db.
67 for (int i = 0; i < num_requests - 1; ++i) { 87 for (int i = 0; i < num_requests - 1; ++i) {
68 int64_t length = (i == (num_requests - 2)) 88 int64_t length = (i == (num_requests - 2))
69 ? slice_size + (bytes_left % slice_size) 89 ? slice_size + (bytes_left % slice_size)
70 : slice_size; 90 : slice_size;
71 CreateRequest(current_offset, length); 91 CreateRequest(current_offset, length);
72 current_offset += slice_size; 92 current_offset += slice_size;
73 } 93 }
74 } 94 }
75 95
96 void ParallelDownloadJob::BuildParallelRequestAfterDelay() {
97 DCHECK(workers_.empty());
98 DCHECK(!requests_sent_);
99 DCHECK(!timer_.IsRunning());
100
101 timer_.Start(FROM_HERE, GetParallelRequestDelayConfig(), this,
102 &ParallelDownloadJob::BuildParallelRequests);
103 }
104
76 void ParallelDownloadJob::BuildParallelRequests() { 105 void ParallelDownloadJob::BuildParallelRequests() {
106 if (requests_sent_)
qinmin 2017/03/16 17:40:36 nit: DCHECK_FALSE(request_sent);
xingliu 2017/03/16 18:18:35 Done.
107 return;
108
77 // Calculate the slices to download and fork parallel requests. 109 // Calculate the slices to download and fork parallel requests.
78 std::vector<DownloadItem::ReceivedSlice> slices_to_download = 110 std::vector<DownloadItem::ReceivedSlice> slices_to_download =
79 FindSlicesToDownload(download_item_->GetReceivedSlices()); 111 FindSlicesToDownload(download_item_->GetReceivedSlices());
80 // The initial request has already been sent, it should cover the first slice. 112 // The initial request has already been sent, it should cover the first slice.
81 DCHECK_GE(slices_to_download[0].offset, initial_request_offset_); 113 DCHECK_GE(slices_to_download[0].offset, initial_request_offset_);
82 DCHECK(initial_request_length_ == DownloadSaveInfo::kLengthFullContent || 114 DCHECK(initial_request_length_ == DownloadSaveInfo::kLengthFullContent ||
83 initial_request_offset_ + initial_request_length_ >= 115 initial_request_offset_ + initial_request_length_ >=
84 slices_to_download[0].offset + 116 slices_to_download[0].offset +
85 slices_to_download[0].received_bytes); 117 slices_to_download[0].received_bytes);
86 if (slices_to_download.size() >= 118 if (slices_to_download.size() >=
87 static_cast<size_t>(GetParallelRequestCountConfig())) { 119 static_cast<size_t>(GetParallelRequestCountConfig())) {
88 // The size of |slices_to_download| should be no larger than 120 // The size of |slices_to_download| should be no larger than
89 // |kParallelRequestCount| unless |kParallelRequestCount| is changed after 121 // |kParallelRequestCount| unless |kParallelRequestCount| is changed after
90 // a download is interrupted. This could happen if we use finch to config 122 // a download is interrupted. This could happen if we use finch to config
91 // the number of parallel requests. 123 // the number of parallel requests.
92 // TODO(qinmin): Get the next |kParallelRequestCount - 1| slices and fork 124 // TODO(qinmin): Get the next |kParallelRequestCount - 1| slices and fork
93 // new requests. For the remaining slices, they will be handled once some 125 // new requests. For the remaining slices, they will be handled once some
94 // of the workers finish their job. 126 // of the workers finish their job.
95 } else { 127 } else {
96 // TODO(qinmin): Check the size of the last slice. If it is huge, we can 128 // TODO(qinmin): Check the size of the last slice. If it is huge, we can
97 // split it into N pieces and pass the last N-1 pirces to different workers. 129 // split it into N pieces and pass the last N-1 pirces to different workers.
98 // Otherwise, just fork |slices_to_download.size()| number of workers. 130 // Otherwise, just fork |slices_to_download.size()| number of workers.
99 } 131 }
132
133 requests_sent_ = true;
100 } 134 }
101 135
102 void ParallelDownloadJob::CreateRequest(int64_t offset, int64_t length) { 136 void ParallelDownloadJob::CreateRequest(int64_t offset, int64_t length) {
103 std::unique_ptr<DownloadWorker> worker = base::MakeUnique<DownloadWorker>(); 137 std::unique_ptr<DownloadWorker> worker = base::MakeUnique<DownloadWorker>();
104 138
105 DCHECK(download_item_); 139 DCHECK(download_item_);
106 StoragePartition* storage_partition = 140 StoragePartition* storage_partition =
107 BrowserContext::GetStoragePartitionForSite( 141 BrowserContext::GetStoragePartitionForSite(
108 download_item_->GetBrowserContext(), download_item_->GetSiteUrl()); 142 download_item_->GetBrowserContext(), download_item_->GetSiteUrl());
109 143
(...skipping 12 matching lines...) Expand all
122 // Subsequent range requests have the same referrer URL as the original 156 // Subsequent range requests have the same referrer URL as the original
123 // download request. 157 // download request.
124 download_params->set_referrer(Referrer(download_item_->GetReferrerUrl(), 158 download_params->set_referrer(Referrer(download_item_->GetReferrerUrl(),
125 blink::WebReferrerPolicyAlways)); 159 blink::WebReferrerPolicyAlways));
126 // Send the request. 160 // Send the request.
127 worker->SendRequest(std::move(download_params)); 161 worker->SendRequest(std::move(download_params));
128 workers_.push_back(std::move(worker)); 162 workers_.push_back(std::move(worker));
129 } 163 }
130 164
131 } // namespace content 165 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/download/parallel_download_job.h ('k') | content/browser/download/parallel_download_utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698