forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Bug: 831648 Change-Id: I3a9525384ca17c05f38748fc3592af3f46f742db Reviewed-on: https://chromium-review.googlesource.com/1089930 Commit-Queue: Sky Malice <skym@chromium.org> Reviewed-by: Gabriel Charette <gab@chromium.org> Reviewed-by: Filip Gorski <fgorski@chromium.org> Reviewed-by: Patrick Noland <pnoland@chromium.org> Cr-Commit-Position: refs/heads/master@{#579566}
- Loading branch information
Sky Malice
authored and
Commit Bot
committed
Jul 31, 2018
1 parent
2de9079
commit 8ff6430
Showing
10 changed files
with
363 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
// Copyright 2018 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "components/feed/core/refresh_throttler.h" | ||
|
||
#include <limits> | ||
#include <set> | ||
#include <utility> | ||
#include <vector> | ||
|
||
#include "base/metrics/field_trial_params.h" | ||
#include "base/metrics/histogram.h" | ||
#include "base/metrics/histogram_base.h" | ||
#include "base/strings/stringprintf.h" | ||
#include "base/time/clock.h" | ||
#include "components/feed/core/pref_names.h" | ||
#include "components/feed/feed_feature_list.h" | ||
#include "components/prefs/pref_registry_simple.h" | ||
#include "components/prefs/pref_service.h" | ||
|
||
namespace feed { | ||
|
||
namespace { | ||
|
||
// Values correspond to ntp_snippets::RequestStatus and histograms.xml | ||
enum class RequestStatus { | ||
kObsolete1 = 0, | ||
kQuotaGranted = 1, | ||
kQuotaExceeded = 2, | ||
kObsolete2 = 3, | ||
kStatusCount = 4 | ||
}; | ||
|
||
// When adding a new type here, extend also the "RequestThrottlerTypes" | ||
// <histogram_suffixes> in histograms.xml with the |name| string. First value in | ||
// the pair is the name, second is the default requests per day. | ||
std::pair<std::string, int> GetThrottlerParams( | ||
UserClassifier::UserClass user_class) { | ||
switch (user_class) { | ||
case UserClassifier::UserClass::kRareNtpUser: | ||
return {"SuggestionFetcherRareNTPUser", 5}; | ||
case UserClassifier::UserClass::kActiveNtpUser: | ||
return {"SuggestionFetcherActiveNTPUser", 20}; | ||
case UserClassifier::UserClass::kActiveSuggestionsConsumer: | ||
return {"SuggestionFetcherActiveSuggestionsConsumer", 20}; | ||
} | ||
} | ||
|
||
} // namespace | ||
|
||
RefreshThrottler::RefreshThrottler(UserClassifier::UserClass user_class, | ||
PrefService* pref_service, | ||
base::Clock* clock) | ||
: pref_service_(pref_service), clock_(clock) { | ||
DCHECK(pref_service); | ||
DCHECK(clock); | ||
|
||
std::pair<std::string, int> throttler_params = GetThrottlerParams(user_class); | ||
name_ = throttler_params.first; | ||
max_requests_per_day_ = base::GetFieldTrialParamByFeatureAsInt( | ||
kInterestFeedContentSuggestions, | ||
base::StringPrintf("quota_%s", name_.c_str()), throttler_params.second); | ||
|
||
// Since the histogram names are dynamic, we cannot use the standard macros | ||
// and we need to lookup the histograms, instead. | ||
int status_count = static_cast<int>(RequestStatus::kStatusCount); | ||
// Corresponds to UMA_HISTOGRAM_ENUMERATION(name, sample, |status_count|). | ||
histogram_request_status_ = base::LinearHistogram::FactoryGet( | ||
base::StringPrintf("NewTabPage.RequestThrottler.RequestStatus_%s", | ||
name_.c_str()), | ||
1, status_count, status_count + 1, | ||
base::HistogramBase::kUmaTargetedHistogramFlag); | ||
// Corresponds to UMA_HISTOGRAM_COUNTS_100(name, sample). | ||
histogram_per_day_ = base::Histogram::FactoryGet( | ||
base::StringPrintf("NewTabPage.RequestThrottler.PerDay_%s", | ||
name_.c_str()), | ||
1, 100, 50, base::HistogramBase::kUmaTargetedHistogramFlag); | ||
} | ||
|
||
// static | ||
void RefreshThrottler::RegisterProfilePrefs(PrefRegistrySimple* registry) { | ||
registry->RegisterIntegerPref(prefs::kThrottlerRequestCount, 0); | ||
registry->RegisterIntegerPref(prefs::kThrottlerRequestsDay, 0); | ||
} | ||
|
||
bool RefreshThrottler::RequestQuota() { | ||
ResetCounterIfDayChanged(); | ||
|
||
// Increment |new_count| in a overflow safe fashion. | ||
int new_count = GetCount(); | ||
if (new_count < std::numeric_limits<int>::max()) { | ||
new_count++; | ||
} | ||
SetCount(new_count); | ||
bool available = (new_count <= GetQuota()); | ||
|
||
histogram_request_status_->Add( | ||
static_cast<int>(available ? RequestStatus::kQuotaGranted | ||
: RequestStatus::kQuotaExceeded)); | ||
|
||
return available; | ||
} | ||
|
||
void RefreshThrottler::ResetCounterIfDayChanged() { | ||
// Grant new quota on local midnight to spread out when clients that start | ||
// making un-throttled requests to server. | ||
int now_day = clock_->Now().LocalMidnight().since_origin().InDays(); | ||
|
||
if (!HasDay()) { | ||
// The counter is used for the first time in this profile. | ||
SetDay(now_day); | ||
} else if (now_day != GetDay()) { | ||
// Day has changed - report the number of requests from the previous day. | ||
histogram_per_day_->Add(GetCount()); | ||
// Reset the counters. | ||
SetCount(0); | ||
SetDay(now_day); | ||
} | ||
} | ||
|
||
int RefreshThrottler::GetQuota() const { | ||
return max_requests_per_day_; | ||
} | ||
|
||
int RefreshThrottler::GetCount() const { | ||
return pref_service_->GetInteger(prefs::kThrottlerRequestCount); | ||
} | ||
|
||
void RefreshThrottler::SetCount(int count) { | ||
pref_service_->SetInteger(prefs::kThrottlerRequestCount, count); | ||
} | ||
|
||
int RefreshThrottler::GetDay() const { | ||
return pref_service_->GetInteger(prefs::kThrottlerRequestsDay); | ||
} | ||
|
||
void RefreshThrottler::SetDay(int day) { | ||
pref_service_->SetInteger(prefs::kThrottlerRequestsDay, day); | ||
} | ||
|
||
bool RefreshThrottler::HasDay() const { | ||
return pref_service_->HasPrefPath(prefs::kThrottlerRequestsDay); | ||
} | ||
|
||
} // namespace feed |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// Copyright 2018 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef COMPONENTS_FEED_CORE_REFRESH_THROTTLER_H_ | ||
#define COMPONENTS_FEED_CORE_REFRESH_THROTTLER_H_ | ||
|
||
#include <string> | ||
|
||
#include "base/macros.h" | ||
#include "components/feed/core/user_classifier.h" | ||
|
||
class PrefRegistrySimple; | ||
class PrefService; | ||
|
||
namespace base { | ||
class Clock; | ||
class HistogramBase; | ||
} // namespace base | ||
|
||
namespace feed { | ||
|
||
// Counts requests to perform refreshes, compares them to a daily quota, and | ||
// reports them to UMA. In the application code, create one local instance for | ||
// each given throttler name, identified by the UserClass. Reports to the same | ||
// histograms that previous NTP implementation used: | ||
// - "NewTabPage.RequestThrottler.RequestStatus_|name|" - status of each | ||
// request; | ||
// - "NewTabPage.RequestThrottler.PerDay_|name|" - the daily count of requests. | ||
class RefreshThrottler { | ||
public: | ||
RefreshThrottler(UserClassifier::UserClass user_class, | ||
PrefService* pref_service, | ||
base::Clock* clock); | ||
|
||
// Registers profile prefs, called from browser_prefs.cc. | ||
static void RegisterProfilePrefs(PrefRegistrySimple* registry); | ||
|
||
// Returns whether quota is available for another request, persists the usage | ||
// of said quota, and reports this information to UMA. | ||
bool RequestQuota(); | ||
|
||
private: | ||
// Also emits the PerDay histogram if the day changed. | ||
void ResetCounterIfDayChanged(); | ||
|
||
int GetQuota() const; | ||
int GetCount() const; | ||
void SetCount(int count); | ||
int GetDay() const; | ||
void SetDay(int day); | ||
bool HasDay() const; | ||
|
||
// Provides durable storage. | ||
PrefService* pref_service_; | ||
|
||
// Used to access current time, injected for testing. | ||
base::Clock* clock_; | ||
|
||
// The name used by this throttler, based off UserClass, which will be used as | ||
// a suffix when constructing histogram or finch param names. | ||
std::string name_; | ||
|
||
// The total requests allowed before RequestQuota() starts returning false, | ||
// reset every time |clock_| changes days. Read from a variation param during | ||
// initialization. | ||
int max_requests_per_day_; | ||
|
||
// The histograms for reporting the requests of the given |type_|. | ||
base::HistogramBase* histogram_request_status_; | ||
base::HistogramBase* histogram_per_day_; | ||
|
||
DISALLOW_COPY_AND_ASSIGN(RefreshThrottler); | ||
}; | ||
|
||
} // namespace feed | ||
|
||
#endif // COMPONENTS_FEED_CORE_REFRESH_THROTTLER_H_ |
Oops, something went wrong.