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

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

Issue 2750713003: Add UMA for estimating disk bandwidth and the time saved with parallel download (Closed)
Patch Set: don't record UMA after pause 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/download_file_impl.h" 5 #include "content/browser/download/download_file_impl.h"
6 6
7 #include <string> 7 #include <string>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 bool is_sparse_file, 64 bool is_sparse_file,
65 base::WeakPtr<DownloadDestinationObserver> observer) 65 base::WeakPtr<DownloadDestinationObserver> observer)
66 : net_log_( 66 : net_log_(
67 net::NetLogWithSource::Make(download_item_net_log.net_log(), 67 net::NetLogWithSource::Make(download_item_net_log.net_log(),
68 net::NetLogSourceType::DOWNLOAD_FILE)), 68 net::NetLogSourceType::DOWNLOAD_FILE)),
69 file_(net_log_), 69 file_(net_log_),
70 save_info_(std::move(save_info)), 70 save_info_(std::move(save_info)),
71 default_download_directory_(default_download_directory), 71 default_download_directory_(default_download_directory),
72 is_sparse_file_(is_sparse_file), 72 is_sparse_file_(is_sparse_file),
73 bytes_seen_(0), 73 bytes_seen_(0),
74 num_active_streams_(0),
75 record_stream_bandwidth_(true),
76 bytes_seen_with_parallel_streams_(0),
77 bytes_seen_without_parallel_streams_(0),
74 received_slices_(received_slices), 78 received_slices_(received_slices),
75 observer_(observer), 79 observer_(observer),
76 weak_factory_(this) { 80 weak_factory_(this) {
77 source_streams_[save_info_->offset] = base::MakeUnique<SourceStream>( 81 source_streams_[save_info_->offset] = base::MakeUnique<SourceStream>(
78 save_info_->offset, DownloadSaveInfo::kLengthFullContent); 82 save_info_->offset, DownloadSaveInfo::kLengthFullContent);
79 DCHECK(source_streams_.size() == static_cast<size_t>(1)); 83 DCHECK(source_streams_.size() == static_cast<size_t>(1));
80 source_streams_[save_info_->offset]->SetByteStream(std::move(stream_reader)); 84 source_streams_[save_info_->offset]->SetByteStream(std::move(stream_reader));
81 85
82 download_item_net_log.AddEvent( 86 download_item_net_log.AddEvent(
83 net::NetLogEventType::DOWNLOAD_FILE_CREATED, 87 net::NetLogEventType::DOWNLOAD_FILE_CREATED,
(...skipping 25 matching lines...) Expand all
109 std::move(save_info_->file), bytes_so_far, 113 std::move(save_info_->file), bytes_so_far,
110 save_info_->hash_of_partial_file, 114 save_info_->hash_of_partial_file,
111 std::move(save_info_->hash_state), is_sparse_file_); 115 std::move(save_info_->hash_state), is_sparse_file_);
112 if (result != DOWNLOAD_INTERRUPT_REASON_NONE) { 116 if (result != DOWNLOAD_INTERRUPT_REASON_NONE) {
113 BrowserThread::PostTask( 117 BrowserThread::PostTask(
114 BrowserThread::UI, FROM_HERE, base::Bind(callback, result)); 118 BrowserThread::UI, FROM_HERE, base::Bind(callback, result));
115 return; 119 return;
116 } 120 }
117 121
118 download_start_ = base::TimeTicks::Now(); 122 download_start_ = base::TimeTicks::Now();
123 last_update_time_ = download_start_;
119 124
120 // Primarily to make reset to zero in restart visible to owner. 125 // Primarily to make reset to zero in restart visible to owner.
121 SendUpdate(); 126 SendUpdate();
122 127
123 // Initial pull from the straw. 128 // Initial pull from the straw.
124 for (auto& source_stream : source_streams_) 129 for (auto& source_stream : source_streams_)
125 RegisterAndActivateStream(source_stream.second.get()); 130 RegisterAndActivateStream(source_stream.second.get());
126 131
127 BrowserThread::PostTask( 132 BrowserThread::PostTask(
128 BrowserThread::UI, FROM_HERE, base::Bind( 133 BrowserThread::UI, FROM_HERE, base::Bind(
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 } 277 }
273 278
274 const base::FilePath& DownloadFileImpl::FullPath() const { 279 const base::FilePath& DownloadFileImpl::FullPath() const {
275 return file_.full_path(); 280 return file_.full_path();
276 } 281 }
277 282
278 bool DownloadFileImpl::InProgress() const { 283 bool DownloadFileImpl::InProgress() const {
279 return file_.in_progress(); 284 return file_.in_progress();
280 } 285 }
281 286
287 void DownloadFileImpl::Pause() {
288 record_stream_bandwidth_ = false;
xingliu 2017/03/17 00:02:15 I think we didn't set it to true again, and didn't
David Trainor- moved to gerrit 2017/03/17 07:25:40 Do we need to reset last_update_time_ on resume as
qinmin 2017/03/17 19:52:54 We don't record UMA even if resume is called, the
qinmin 2017/03/17 19:52:55 we should stop recording if a download is ever pau
289 }
290
282 void DownloadFileImpl::StreamActive(SourceStream* source_stream) { 291 void DownloadFileImpl::StreamActive(SourceStream* source_stream) {
283 DCHECK(source_stream->stream_reader()); 292 DCHECK(source_stream->stream_reader());
284 base::TimeTicks start(base::TimeTicks::Now()); 293 base::TimeTicks start(base::TimeTicks::Now());
285 base::TimeTicks now; 294 base::TimeTicks now;
286 scoped_refptr<net::IOBuffer> incoming_data; 295 scoped_refptr<net::IOBuffer> incoming_data;
287 size_t incoming_data_size = 0; 296 size_t incoming_data_size = 0;
288 size_t total_incoming_data_size = 0; 297 size_t total_incoming_data_size = 0;
289 size_t num_buffers = 0; 298 size_t num_buffers = 0;
290 bool should_terminate = false; 299 bool should_terminate = false;
291 ByteStreamReader::StreamState state(ByteStreamReader::STREAM_EMPTY); 300 ByteStreamReader::StreamState state(ByteStreamReader::STREAM_EMPTY);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 // Shut down processing and signal an error to our observer. 369 // Shut down processing and signal an error to our observer.
361 // Our observer will clean us up. 370 // Our observer will clean us up.
362 source_stream->stream_reader()->RegisterCallback(base::Closure()); 371 source_stream->stream_reader()->RegisterCallback(base::Closure());
363 weak_factory_.InvalidateWeakPtrs(); 372 weak_factory_.InvalidateWeakPtrs();
364 SendUpdate(); // Make info up to date before error. 373 SendUpdate(); // Make info up to date before error.
365 std::unique_ptr<crypto::SecureHash> hash_state = file_.Finish(); 374 std::unique_ptr<crypto::SecureHash> hash_state = file_.Finish();
366 BrowserThread::PostTask( 375 BrowserThread::PostTask(
367 BrowserThread::UI, FROM_HERE, 376 BrowserThread::UI, FROM_HERE,
368 base::Bind(&DownloadDestinationObserver::DestinationError, observer_, 377 base::Bind(&DownloadDestinationObserver::DestinationError, observer_,
369 reason, TotalBytesReceived(), base::Passed(&hash_state))); 378 reason, TotalBytesReceived(), base::Passed(&hash_state)));
379 num_active_streams_--;
370 } else if (state == ByteStreamReader::STREAM_COMPLETE || should_terminate) { 380 } else if (state == ByteStreamReader::STREAM_COMPLETE || should_terminate) {
371 // Signal successful completion or termination of the current stream. 381 // Signal successful completion or termination of the current stream.
372 source_stream->stream_reader()->RegisterCallback(base::Closure()); 382 source_stream->stream_reader()->RegisterCallback(base::Closure());
373 source_stream->set_finished(true); 383 source_stream->set_finished(true);
384 num_active_streams_--;
374 385
375 // Inform observers. 386 // Inform observers.
376 SendUpdate(); 387 SendUpdate();
377 388
378 // TODO(xingliu): Use slice info to determine if the file is fully 389 // TODO(xingliu): Use slice info to determine if the file is fully
379 // downloaded. 390 // downloaded.
380 bool all_stream_complete = true; 391 bool all_stream_complete = true;
381 for (auto& stream : source_streams_) { 392 for (auto& stream : source_streams_) {
382 if (!stream.second->is_finished()) { 393 if (!stream.second->is_finished()) {
383 all_stream_complete = false; 394 all_stream_complete = false;
384 break; 395 break;
385 } 396 }
386 } 397 }
387 398
388 // All the stream reader are completed, shut down file IO processing. 399 // All the stream reader are completed, shut down file IO processing.
389 if (all_stream_complete) { 400 if (all_stream_complete) {
390 RecordFileBandwidth(bytes_seen_, disk_writes_time_, 401 RecordFileBandwidth(bytes_seen_, disk_writes_time_,
391 base::TimeTicks::Now() - download_start_); 402 base::TimeTicks::Now() - download_start_);
403 if (is_sparse_file_) {
404 RecordParallelDownloadStats(bytes_seen_with_parallel_streams_,
405 download_time_with_parallel_streams_,
406 bytes_seen_without_parallel_streams_,
407 download_time_without_parallel_streams_);
408 }
392 weak_factory_.InvalidateWeakPtrs(); 409 weak_factory_.InvalidateWeakPtrs();
393 std::unique_ptr<crypto::SecureHash> hash_state = file_.Finish(); 410 std::unique_ptr<crypto::SecureHash> hash_state = file_.Finish();
394 update_timer_.reset(); 411 update_timer_.reset();
395 BrowserThread::PostTask( 412 BrowserThread::PostTask(
396 BrowserThread::UI, FROM_HERE, 413 BrowserThread::UI, FROM_HERE,
397 base::Bind(&DownloadDestinationObserver::DestinationCompleted, 414 base::Bind(&DownloadDestinationObserver::DestinationCompleted,
398 observer_, TotalBytesReceived(), 415 observer_, TotalBytesReceived(),
399 base::Passed(&hash_state))); 416 base::Passed(&hash_state)));
400 } 417 }
401 } 418 }
402 if (net_log_.IsCapturing()) { 419 if (net_log_.IsCapturing()) {
403 net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_STREAM_DRAINED, 420 net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_STREAM_DRAINED,
404 base::Bind(&FileStreamDrainedNetLogCallback, 421 base::Bind(&FileStreamDrainedNetLogCallback,
405 total_incoming_data_size, num_buffers)); 422 total_incoming_data_size, num_buffers));
406 } 423 }
407 } 424 }
408 425
409 void DownloadFileImpl::RegisterAndActivateStream(SourceStream* source_stream) { 426 void DownloadFileImpl::RegisterAndActivateStream(SourceStream* source_stream) {
410 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 427 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
411 ByteStreamReader* stream_reader = source_stream->stream_reader(); 428 ByteStreamReader* stream_reader = source_stream->stream_reader();
412 if (stream_reader) { 429 if (stream_reader) {
413 stream_reader->RegisterCallback(base::Bind(&DownloadFileImpl::StreamActive, 430 stream_reader->RegisterCallback(base::Bind(&DownloadFileImpl::StreamActive,
414 weak_factory_.GetWeakPtr(), 431 weak_factory_.GetWeakPtr(),
415 source_stream)); 432 source_stream));
416 StreamActive(source_stream); 433 StreamActive(source_stream);
434 num_active_streams_++;
417 } 435 }
418 } 436 }
419 437
420 int64_t DownloadFileImpl::TotalBytesReceived() const { 438 int64_t DownloadFileImpl::TotalBytesReceived() const {
421 return file_.bytes_so_far(); 439 return file_.bytes_so_far();
422 } 440 }
423 441
424 void DownloadFileImpl::SendUpdate() { 442 void DownloadFileImpl::SendUpdate() {
425 // TODO(qinmin): For each active stream, add the slice it has written so 443 // TODO(qinmin): For each active stream, add the slice it has written so
426 // far along with received_slices_. 444 // far along with received_slices_.
427 BrowserThread::PostTask( 445 BrowserThread::PostTask(
428 BrowserThread::UI, FROM_HERE, 446 BrowserThread::UI, FROM_HERE,
429 base::Bind(&DownloadDestinationObserver::DestinationUpdate, observer_, 447 base::Bind(&DownloadDestinationObserver::DestinationUpdate, observer_,
430 TotalBytesReceived(), rate_estimator_.GetCountPerSecond(), 448 TotalBytesReceived(), rate_estimator_.GetCountPerSecond(),
431 received_slices_)); 449 received_slices_));
432 } 450 }
433 451
434 void DownloadFileImpl::WillWriteToDisk(size_t data_len) { 452 void DownloadFileImpl::WillWriteToDisk(size_t data_len) {
435 if (!update_timer_->IsRunning()) { 453 if (!update_timer_->IsRunning()) {
436 update_timer_->Start(FROM_HERE, 454 update_timer_->Start(FROM_HERE,
437 base::TimeDelta::FromMilliseconds(kUpdatePeriodMs), 455 base::TimeDelta::FromMilliseconds(kUpdatePeriodMs),
438 this, &DownloadFileImpl::SendUpdate); 456 this, &DownloadFileImpl::SendUpdate);
439 } 457 }
440 rate_estimator_.Increment(data_len); 458 rate_estimator_.Increment(data_len);
459 if (is_sparse_file_) {
460 base::TimeTicks now = base::TimeTicks::Now();
461 base::TimeDelta time_elapsed = (now - last_update_time_);
462 last_update_time_ = now;
463 if (num_active_streams_ > 1) {
464 download_time_with_parallel_streams_ += time_elapsed;
465 bytes_seen_with_parallel_streams_ += data_len;
466 } else {
467 download_time_without_parallel_streams_ += time_elapsed;
468 bytes_seen_without_parallel_streams_ += data_len;
469 }
470 }
441 } 471 }
442 472
443 DownloadFileImpl::RenameParameters::RenameParameters( 473 DownloadFileImpl::RenameParameters::RenameParameters(
444 RenameOption option, 474 RenameOption option,
445 const base::FilePath& new_path, 475 const base::FilePath& new_path,
446 const RenameCompletionCallback& completion_callback) 476 const RenameCompletionCallback& completion_callback)
447 : option(option), 477 : option(option),
448 new_path(new_path), 478 new_path(new_path),
449 retries_left(kMaxRenameRetries), 479 retries_left(kMaxRenameRetries),
450 completion_callback(completion_callback) {} 480 completion_callback(completion_callback) {}
451 481
452 DownloadFileImpl::RenameParameters::~RenameParameters() {} 482 DownloadFileImpl::RenameParameters::~RenameParameters() {}
453 483
454 } // namespace content 484 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698