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

Unified Diff: chrome/browser/translate/translate_language_list.cc

Issue 15949022: Translate: language list smart updater (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: nits for retry Created 7 years, 6 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/translate/translate_language_list.cc
diff --git a/chrome/browser/translate/translate_language_list.cc b/chrome/browser/translate/translate_language_list.cc
index 597ca46b80d185c2ecfebead8b25b740e8519463..5e4404bb59f5dad5208fdb4ed9e912071ac7f5ae 100644
--- a/chrome/browser/translate/translate_language_list.cc
+++ b/chrome/browser/translate/translate_language_list.cc
@@ -6,6 +6,7 @@
#include <set>
+#include "base/bind.h"
#include "base/json/json_reader.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
@@ -104,8 +105,13 @@ const char kAlphaLanguageQueryName[] = "alpha";
const char kAlphaLanguageQueryValue[] = "1";
// Retry parameter for fetching supporting language list.
-const int kMaxRetryLanguageListFetch = 5;
+const int kMaxRetryLanguageListFetchOn5xx = 5;
+// Retry parameter for LanguageListFetcher.
+const int kMaxRetryLanguageListFetch = 16;
+
+// Assign following IDs to URLFetchers so that tests can distinguish each
+// request in order to simiulate respectively.
const int kFetcherIdForLanguageList = 1;
const int kFetcherIdForAlphaLanguageList = 2;
@@ -176,33 +182,107 @@ void SetSupportedLanguages(const std::string& language_list,
NotifyEvent(__LINE__, message);
}
-// Creates URLFetcher, sets arguments to start, and returns the object.
-net::URLFetcher* CreateAndStartFetch(int id,
- const GURL& url,
- net::URLFetcherDelegate* delegate) {
- DCHECK(delegate);
+// Check if |n| is 2^n (n >= 0).
+bool IsOneHot(int n) {
MAD 2013/06/10 18:28:10 I would prefer to name this: IsPowerOfTwo. And he
Takashi Toyoshima 2013/06/12 05:20:43 I'll stop to use exponential backoff here. Because
+ int hot_count = 0;
+ for (int bit = 1; bit != 0; bit <<= 1)
+ if (n & bit)
+ hot_count++;
+ return hot_count == 1;
+}
+
+} // namespace
+
+TranslateLanguageList::LanguageListFetcher::LanguageListFetcher(
+ bool include_alpha_languages)
+ : include_alpha_languages_(include_alpha_languages),
+ state_(IDLE),
+ retry_count_(0) {
MAD 2013/06/10 18:28:10 You never reset it to 0, so it's not just retries,
Takashi Toyoshima 2013/06/12 05:20:43 If I reset retry_count whenever a request is issue
+}
+
+TranslateLanguageList::LanguageListFetcher::~LanguageListFetcher() {
+}
+
+bool TranslateLanguageList::LanguageListFetcher::Request(
+ const TranslateLanguageList::LanguageListFetcher::Callback& callback) {
+ // This function is not supporsed to be called before previous operaion is not
MAD 2013/06/10 18:28:10 supporsed -> supposed
Takashi Toyoshima 2013/06/12 05:20:43 Done.
+ // finished.
+ if (state_ == REQUESTING) {
+ NOTREACHED();
+ return false;
+ }
+
+ // Omit requests to realize an exponential backoff'd retries.
+ // Request will be issued when |retry_count_| is 2^n (n >= 0) and it doesn't
+ // reach to limitation.
+ if (retry_count_ >= (1 << kMaxRetryLanguageListFetch)) {
+ NotifyEvent(__LINE__, "Request is omitted due to retry limitation");
+ return false;
+ }
+ if (!IsOneHot(++retry_count_)) {
MAD 2013/06/10 18:28:10 Actually, the URLFetcher already supports backoff
Takashi Toyoshima 2013/06/12 05:20:43 Yes. But it works only against HTTP status 5xx. Th
+ NotifyEvent(__LINE__, "Request is omitted due to exponential backoff");
+ return false;
+ }
+
+ state_ = REQUESTING;
+ callback_ = callback;
+
+ GURL url = GURL(kLanguageListFetchURL);
+ url = TranslateURLUtil::AddHostLocaleToUrl(url);
+ url = TranslateURLUtil::AddApiKeyToUrl(url);
+ if (include_alpha_languages_) {
+ url = net::AppendQueryParameter(url,
+ kAlphaLanguageQueryName,
+ kAlphaLanguageQueryValue);
+ }
+
std::string message = base::StringPrintf(
"%s list fetch starts (URL: %s)",
- (id == kFetcherIdForLanguageList) ? "Language" : "Alpha language",
+ include_alpha_languages_ ? "Language" : "Alpha language",
url.spec().c_str());
NotifyEvent(__LINE__, message);
- scoped_ptr<net::URLFetcher> fetcher;
- fetcher.reset(net::URLFetcher::Create(id,
- url,
- net::URLFetcher::GET,
- delegate));
- fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
- net::LOAD_DO_NOT_SAVE_COOKIES);
- fetcher->SetRequestContext(g_browser_process->system_request_context());
- fetcher->SetMaxRetriesOn5xx(kMaxRetryLanguageListFetch);
- fetcher->Start();
-
- return fetcher.release();
+ fetcher_.reset(net::URLFetcher::Create(
+ include_alpha_languages_ ? kFetcherIdForAlphaLanguageList :
+ kFetcherIdForLanguageList,
+ url,
+ net::URLFetcher::GET,
+ this));
+ fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
+ net::LOAD_DO_NOT_SAVE_COOKIES);
+ fetcher_->SetRequestContext(g_browser_process->system_request_context());
+ fetcher_->SetMaxRetriesOn5xx(kMaxRetryLanguageListFetchOn5xx);
+ fetcher_->Start();
+
+ return true;
}
-} // namespace
+void TranslateLanguageList::LanguageListFetcher::OnURLFetchComplete(
+ const net::URLFetcher* source) {
+ DCHECK(fetcher_.get() == source);
+ std::string data;
+ if (source->GetStatus().status() == net::URLRequestStatus::SUCCESS &&
+ source->GetResponseCode() == net::HTTP_OK) {
+ state_ = COMPLETED;
+ source->GetResponseAsString(&data);
+ std::string message = base::StringPrintf(
+ "%s list is updated",
+ include_alpha_languages_ ? "Alpha language" : "Language");
+ NotifyEvent(__LINE__, message);
+ } else {
+ state_ = FAILED;
+ std::string message = base::StringPrintf(
+ "Failed to Fetch languages from: %s",
+ source->GetURL().spec().c_str());
+ NotifyEvent(__LINE__, message);
+ }
+
+ scoped_ptr<const net::URLFetcher> delete_ptr(fetcher_.release());
+ callback_.Run(include_alpha_languages_, state_ == COMPLETED, data);
+}
+
+// Transfer URLFetcher's ownership before invoking a callback.
// This must be kept in sync with the &cb= value in the kLanguageListFetchURL.
const char TranslateLanguageList::kLanguageListCallbackName[] = "sl(";
const char TranslateLanguageList::kTargetLanguagesKey[] = "tl";
@@ -214,42 +294,15 @@ TranslateLanguageList::TranslateLanguageList() {
for (size_t i = 0; i < arraysize(kDefaultSupportedLanguages); ++i)
supported_languages_.insert(kDefaultSupportedLanguages[i]);
UpdateSupportedLanguages();
-}
-TranslateLanguageList::~TranslateLanguageList() {}
+ language_list_fetcher_.reset(new LanguageListFetcher(false));
+ alpha_language_list_fetcher_.reset(new LanguageListFetcher(true));
-void TranslateLanguageList::OnURLFetchComplete(const net::URLFetcher* source) {
- scoped_ptr<const net::URLFetcher> delete_ptr;
+ net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
+}
- if (source->GetStatus().status() == net::URLRequestStatus::SUCCESS &&
- source->GetResponseCode() == net::HTTP_OK) {
- std::string data;
- source->GetResponseAsString(&data);
- if (language_list_fetcher_.get() == source) {
- NotifyEvent(__LINE__, "Language list is updated");
- delete_ptr.reset(language_list_fetcher_.release());
- SetSupportedLanguages(data, &supported_languages_);
- } else if (alpha_language_list_fetcher_.get() == source) {
- NotifyEvent(__LINE__, "Alpha language list is updated");
- delete_ptr.reset(alpha_language_list_fetcher_.release());
- SetSupportedLanguages(data, &supported_alpha_languages_);
- } else {
- NOTREACHED();
- }
- UpdateSupportedLanguages();
- } else {
- // TODO(toyoshim): Try again. http://crbug.com/244202 .
- // Also In CrOS, FetchLanguageList is not called at launching Chrome. It
- // will solve this problem that check if FetchLanguageList is already
- // called, and call it if needed in InitSupportedLanguage().
- std::string message = base::StringPrintf(
- "%s list update fails (Status: %d, URL: %s)",
- (language_list_fetcher_.get() == source) ? "Language" :
- "Alpha language",
- source->GetResponseCode(),
- source->GetOriginalURL().spec().c_str());
- NotifyEvent(__LINE__, message);
- }
+TranslateLanguageList::~TranslateLanguageList() {
+ net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
}
void TranslateLanguageList::GetSupportedLanguages(
@@ -258,6 +311,10 @@ void TranslateLanguageList::GetSupportedLanguages(
std::set<std::string>::const_iterator iter = all_supported_languages_.begin();
for (; iter != all_supported_languages_.end(); ++iter)
languages->push_back(*iter);
+
+ // Update language lists if they are not updated after Chrome was launched
+ // for later requests.
+ RequestLanguageList();
}
std::string TranslateLanguageList::GetLanguageCode(
@@ -284,31 +341,50 @@ bool TranslateLanguageList::IsAlphaLanguage(const std::string& language) {
}
void TranslateLanguageList::RequestLanguageList() {
- if (language_list_fetcher_.get() || alpha_language_list_fetcher_.get())
+ if (language_list_fetcher_.get() &&
+ (language_list_fetcher_->state() == LanguageListFetcher::IDLE ||
+ language_list_fetcher_->state() == LanguageListFetcher::FAILED)) {
+ language_list_fetcher_->Request(
+ base::Bind(&TranslateLanguageList::OnLanguageListFetchComplete,
+ base::Unretained(this)));
+ }
+
+ if (alpha_language_list_fetcher_.get() &&
+ (alpha_language_list_fetcher_->state() == LanguageListFetcher::IDLE ||
+ alpha_language_list_fetcher_->state() == LanguageListFetcher::FAILED)) {
+ alpha_language_list_fetcher_->Request(
+ base::Bind(&TranslateLanguageList::OnLanguageListFetchComplete,
+ base::Unretained(this)));
+ }
+}
+
+void TranslateLanguageList::OnNetworkChanged(
+ net::NetworkChangeNotifier::ConnectionType type) {
+ std::string message = base::StringPrintf("OnNetworkChanged: %d, %s", type,
+ net::NetworkChangeNotifier::IsOffline() ? "offline" : "online");
+ NotifyEvent(__LINE__, message);
+
+ if (net::NetworkChangeNotifier::IsOffline())
return;
- // Fetch the stable language list.
- GURL language_list_fetch_url = GURL(kLanguageListFetchURL);
- language_list_fetch_url =
- TranslateURLUtil::AddHostLocaleToUrl(language_list_fetch_url);
- language_list_fetch_url =
- TranslateURLUtil::AddApiKeyToUrl(language_list_fetch_url);
-
- language_list_fetcher_.reset(
- CreateAndStartFetch(kFetcherIdForLanguageList,
- language_list_fetch_url,
- this));
-
- // Fetch the alpha language list.
- language_list_fetch_url = net::AppendQueryParameter(
- language_list_fetch_url,
- kAlphaLanguageQueryName,
- kAlphaLanguageQueryValue);
-
- alpha_language_list_fetcher_.reset(
- CreateAndStartFetch(kFetcherIdForAlphaLanguageList,
- language_list_fetch_url,
- this));
+ RequestLanguageList();
+}
+
+void TranslateLanguageList::OnLanguageListFetchComplete(
+ bool include_alpha_languages,
+ bool success,
+ const std::string& data) {
+ if (!success)
MAD 2013/06/10 18:28:10 You don't actually retry on failures, and you don'
Takashi Toyoshima 2013/06/12 05:20:43 No. It was invoked in GetSupportedLanguages() if t
+ return;
+
+ if (!include_alpha_languages) {
+ SetSupportedLanguages(data, &supported_languages_);
+ language_list_fetcher_.reset();
+ } else {
+ SetSupportedLanguages(data, &supported_alpha_languages_);
+ alpha_language_list_fetcher_.reset();
+ }
+ UpdateSupportedLanguages();
}
void TranslateLanguageList::UpdateSupportedLanguages() {
« no previous file with comments | « chrome/browser/translate/translate_language_list.h ('k') | chrome/browser/translate/translate_manager_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698