Commit 0d44b274 authored by hidehiko@chromium.org's avatar hidehiko@chromium.org

Update the number of fetched files more frequently.

BUG=128141
TEST=ran manually, ran browser_tests, and ran unit_tests --gtest_filter=GData*



Review URL: https://chromiumcodereview.appspot.com/10827098

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@149893 0039d316-1c4b-4281-b951-d872f2087c98
parent 77f846c6
...@@ -55,6 +55,9 @@ const int kGDataUpdateCheckIntervalInSec = 5; ...@@ -55,6 +55,9 @@ const int kGDataUpdateCheckIntervalInSec = 5;
const int kGDataUpdateCheckIntervalInSec = 60; const int kGDataUpdateCheckIntervalInSec = 60;
#endif #endif
// Update the fetch progress UI per every this number of feeds.
const int kFetchUiUpdateStep = 10;
// Schedule for dumping root file system proto buffers to disk depending its // Schedule for dumping root file system proto buffers to disk depending its
// total protobuffer size in MB. // total protobuffer size in MB.
typedef struct { typedef struct {
...@@ -585,6 +588,36 @@ void GDataWapiFeedLoader::RemoveObserver(Observer* observer) { ...@@ -585,6 +588,36 @@ void GDataWapiFeedLoader::RemoveObserver(Observer* observer) {
observers_.RemoveObserver(observer); observers_.RemoveObserver(observer);
} }
// Defines set of parameters sent to callback OnNotifyDocumentFeedFetched().
// This is a trick to update the number of fetched documents frequently on
// UI. Due to performance reason, we need to fetch a number of files at
// a time. However, it'll take long time, and a user has no way to know
// the current update state. In order to make users confortable,
// we increment the number of fetched documents with more frequent but smaller
// steps than actual fetching.
struct GetDocumentsUiState {
explicit GetDocumentsUiState(base::TimeTicks start_time)
: num_fetched_documents(0),
num_showing_documents(0),
start_time(start_time),
weak_ptr_factory(this) {
}
// The number of fetched documents.
int num_fetched_documents;
// The number documents shown on UI.
int num_showing_documents;
// When the UI update has started.
base::TimeTicks start_time;
// Time elapsed since the feed fetching was started.
base::TimeDelta feed_fetching_elapsed_time;
base::WeakPtrFactory<GetDocumentsUiState> weak_ptr_factory;
};
// Defines set of parameters sent to callback OnGetDocuments(). // Defines set of parameters sent to callback OnGetDocuments().
// TODO(satorux): Move this to a new file: crbug.com/138268 // TODO(satorux): Move this to a new file: crbug.com/138268
struct GetDocumentsParams { struct GetDocumentsParams {
...@@ -595,7 +628,8 @@ struct GetDocumentsParams { ...@@ -595,7 +628,8 @@ struct GetDocumentsParams {
const FilePath& search_file_path, const FilePath& search_file_path,
const std::string& search_query, const std::string& search_query,
const std::string& directory_resource_id, const std::string& directory_resource_id,
const FindEntryCallback& callback); const FindEntryCallback& callback,
GetDocumentsUiState* ui_state);
~GetDocumentsParams(); ~GetDocumentsParams();
// Changestamps are positive numbers in increasing order. The difference // Changestamps are positive numbers in increasing order. The difference
...@@ -612,6 +646,7 @@ struct GetDocumentsParams { ...@@ -612,6 +646,7 @@ struct GetDocumentsParams {
std::string search_query; std::string search_query;
std::string directory_resource_id; std::string directory_resource_id;
FindEntryCallback callback; FindEntryCallback callback;
scoped_ptr<GetDocumentsUiState> ui_state;
}; };
GetDocumentsParams::GetDocumentsParams( GetDocumentsParams::GetDocumentsParams(
...@@ -622,7 +657,8 @@ GetDocumentsParams::GetDocumentsParams( ...@@ -622,7 +657,8 @@ GetDocumentsParams::GetDocumentsParams(
const FilePath& search_file_path, const FilePath& search_file_path,
const std::string& search_query, const std::string& search_query,
const std::string& directory_resource_id, const std::string& directory_resource_id,
const FindEntryCallback& callback) const FindEntryCallback& callback,
GetDocumentsUiState* ui_state)
: start_changestamp(start_changestamp), : start_changestamp(start_changestamp),
root_feed_changestamp(root_feed_changestamp), root_feed_changestamp(root_feed_changestamp),
feed_list(feed_list), feed_list(feed_list),
...@@ -630,7 +666,8 @@ GetDocumentsParams::GetDocumentsParams( ...@@ -630,7 +666,8 @@ GetDocumentsParams::GetDocumentsParams(
search_file_path(search_file_path), search_file_path(search_file_path),
search_query(search_query), search_query(search_query),
directory_resource_id(directory_resource_id), directory_resource_id(directory_resource_id),
callback(callback) { callback(callback),
ui_state(ui_state) {
} }
GetDocumentsParams::~GetDocumentsParams() { GetDocumentsParams::~GetDocumentsParams() {
...@@ -1086,7 +1123,8 @@ void GDataWapiFeedLoader::LoadFromServer( ...@@ -1086,7 +1123,8 @@ void GDataWapiFeedLoader::LoadFromServer(
search_file_path, search_file_path,
search_query, search_query,
directory_resource_id, directory_resource_id,
entry_found_callback)), entry_found_callback,
NULL)),
start_time)); start_time));
} }
...@@ -2834,13 +2872,29 @@ void GDataWapiFeedLoader::OnGetDocuments( ...@@ -2834,13 +2872,29 @@ void GDataWapiFeedLoader::OnGetDocuments(
for (size_t i = 0; i < params->feed_list->size(); ++i) for (size_t i = 0; i < params->feed_list->size(); ++i)
num_accumulated_entries += params->feed_list->at(i)->entries().size(); num_accumulated_entries += params->feed_list->at(i)->entries().size();
// Notify the observers that a document feed is fetched.
FOR_EACH_OBSERVER(Observer, observers_,
OnDocumentFeedFetched(num_accumulated_entries));
// Check if we need to collect more data to complete the directory list. // Check if we need to collect more data to complete the directory list.
if (params->should_fetch_multiple_feeds && has_next_feed_url && if (params->should_fetch_multiple_feeds && has_next_feed_url &&
!next_feed_url.is_empty()) { !next_feed_url.is_empty()) {
// Post an UI update event to make the UI smoother.
GetDocumentsUiState* ui_state = params->ui_state.get();
if (ui_state == NULL) {
ui_state = new GetDocumentsUiState(base::TimeTicks::Now());
params->ui_state.reset(ui_state);
}
DCHECK(ui_state);
if ((ui_state->num_fetched_documents - ui_state->num_showing_documents)
< kFetchUiUpdateStep) {
// Currently the UI update is stopped. Start UI periodic callback.
MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&GDataWapiFeedLoader::OnNotifyDocumentFeedFetched,
weak_ptr_factory_.GetWeakPtr(),
ui_state->weak_ptr_factory.GetWeakPtr()));
}
ui_state->num_fetched_documents = num_accumulated_entries;
ui_state->feed_fetching_elapsed_time = base::TimeTicks::Now() - start_time;
// Kick of the remaining part of the feeds. // Kick of the remaining part of the feeds.
documents_service_->GetDocuments( documents_service_->GetDocuments(
next_feed_url, next_feed_url,
...@@ -2860,11 +2914,16 @@ void GDataWapiFeedLoader::OnGetDocuments( ...@@ -2860,11 +2914,16 @@ void GDataWapiFeedLoader::OnGetDocuments(
params->search_file_path, params->search_file_path,
params->search_query, params->search_query,
params->directory_resource_id, params->directory_resource_id,
params->callback)), params->callback,
params->ui_state.release())),
start_time)); start_time));
return; return;
} }
// Notify the observers that a document feed is fetched.
FOR_EACH_OBSERVER(Observer, observers_,
OnDocumentFeedFetched(num_accumulated_entries));
UMA_HISTOGRAM_TIMES("Gdata.EntireFeedLoadTime", UMA_HISTOGRAM_TIMES("Gdata.EntireFeedLoadTime",
base::TimeTicks::Now() - start_time); base::TimeTicks::Now() - start_time);
...@@ -2872,6 +2931,43 @@ void GDataWapiFeedLoader::OnGetDocuments( ...@@ -2872,6 +2931,43 @@ void GDataWapiFeedLoader::OnGetDocuments(
callback.Run(params, error); callback.Run(params, error);
} }
void GDataWapiFeedLoader::OnNotifyDocumentFeedFetched(
base::WeakPtr<GetDocumentsUiState> ui_state) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (!ui_state) {
// The ui state instance is already released, which means the fetching
// is done and we don't need to update any more.
return;
}
base::TimeDelta elapsed_time =
base::TimeTicks::Now() - ui_state->start_time;
if (ui_state->num_showing_documents + kFetchUiUpdateStep <=
ui_state->num_fetched_documents) {
ui_state->num_showing_documents += kFetchUiUpdateStep;
FOR_EACH_OBSERVER(Observer, observers_,
OnDocumentFeedFetched(ui_state->num_showing_documents));
int num_remaining_ui_updates =
(ui_state->num_fetched_documents - ui_state->num_showing_documents)
/ kFetchUiUpdateStep;
if (num_remaining_ui_updates > 0) {
// Heuristically, we use fetched time duration to calculate the next
// UI update timing.
base::TimeDelta remaining_duration =
ui_state->feed_fetching_elapsed_time - elapsed_time;
MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&GDataWapiFeedLoader::OnNotifyDocumentFeedFetched,
weak_ptr_factory_.GetWeakPtr(),
ui_state->weak_ptr_factory.GetWeakPtr()),
remaining_duration / num_remaining_ui_updates);
}
}
}
void GDataWapiFeedLoader::LoadFromCache( void GDataWapiFeedLoader::LoadFromCache(
bool should_load_from_server, bool should_load_from_server,
const FilePath& search_file_path, const FilePath& search_file_path,
......
...@@ -35,6 +35,7 @@ class DocumentsServiceInterface; ...@@ -35,6 +35,7 @@ class DocumentsServiceInterface;
class DriveWebAppsRegistryInterface; class DriveWebAppsRegistryInterface;
class GDataWapiFeedLoader; class GDataWapiFeedLoader;
struct GetDocumentsParams; struct GetDocumentsParams;
struct GetDocumentsUiState;
struct UploadFileInfo; struct UploadFileInfo;
namespace { namespace {
...@@ -171,6 +172,10 @@ class GDataWapiFeedLoader { ...@@ -171,6 +172,10 @@ class GDataWapiFeedLoader {
GDataErrorCode status, GDataErrorCode status,
scoped_ptr<base::Value> data); scoped_ptr<base::Value> data);
// Callback for handling UI updates caused by document fetching.
void OnNotifyDocumentFeedFetched(
base::WeakPtr<GetDocumentsUiState> ui_state);
// Save filesystem as proto file. // Save filesystem as proto file.
void SaveFileSystemAsProto(); void SaveFileSystemAsProto();
......
...@@ -69,9 +69,9 @@ const char kUploadContentLength[] = "X-Upload-Content-Length: "; ...@@ -69,9 +69,9 @@ const char kUploadContentLength[] = "X-Upload-Content-Length: ";
// Use smaller 'page' size while debugging to ensure we hit feed reload // Use smaller 'page' size while debugging to ensure we hit feed reload
// almost always. Be careful not to use something too small on account that // almost always. Be careful not to use something too small on account that
// have many items because server side 503 error might kick in. // have many items because server side 503 error might kick in.
const int kMaxDocumentsPerFeed = 1000; const int kMaxDocumentsPerFeed = 500;
#else #else
const int kMaxDocumentsPerFeed = 1000; const int kMaxDocumentsPerFeed = 500;
#endif #endif
const char kFeedField[] = "feed"; const char kFeedField[] = "feed";
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment