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

Side by Side Diff: components/ntp_snippets/remote/scheduling_remote_suggestions_provider.cc

Issue 2702223004: [Remote suggestions] Move all decisions to fetch to the scheduler (Closed)
Patch Set: Fixing an embarassing bug :) 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "components/ntp_snippets/remote/scheduling_remote_suggestions_provider. h" 5 #include "components/ntp_snippets/remote/scheduling_remote_suggestions_provider. h"
6 6
7 #include <random> 7 #include <random>
8 #include <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 arraysize(kFetchingIntervalParamNameActiveSuggestionsConsumer), 88 arraysize(kFetchingIntervalParamNameActiveSuggestionsConsumer),
89 "Fill in all the info for fetching intervals."); 89 "Fill in all the info for fetching intervals.");
90 90
91 const char* kTriggerTypeNames[] = {"persistent_scheduler_wake_up", "ntp_opened", 91 const char* kTriggerTypeNames[] = {"persistent_scheduler_wake_up", "ntp_opened",
92 "browser_foregrounded", 92 "browser_foregrounded",
93 "browser_cold_start"}; 93 "browser_cold_start"};
94 94
95 const char* kTriggerTypesParamName = "scheduler_trigger_types"; 95 const char* kTriggerTypesParamName = "scheduler_trigger_types";
96 const char* kTriggerTypesParamValueForEmptyList = "-"; 96 const char* kTriggerTypesParamValueForEmptyList = "-";
97 97
98 const int kBlockBackgroundFetchesMinutesAfterClearingHistory = 30;
99
98 // Returns the time interval to use for scheduling remote suggestion fetches for 100 // Returns the time interval to use for scheduling remote suggestion fetches for
99 // the given interval and user_class. 101 // the given interval and user_class.
100 base::TimeDelta GetDesiredFetchingInterval( 102 base::TimeDelta GetDesiredFetchingInterval(
101 FetchingInterval interval, 103 FetchingInterval interval,
102 UserClassifier::UserClass user_class) { 104 UserClassifier::UserClass user_class) {
103 DCHECK(interval != FetchingInterval::COUNT); 105 DCHECK(interval != FetchingInterval::COUNT);
104 const unsigned int index = static_cast<unsigned int>(interval); 106 const unsigned int index = static_cast<unsigned int>(interval);
105 DCHECK(index < arraysize(kDefaultFetchingIntervalHoursRareNtpUser)); 107 DCHECK(index < arraysize(kDefaultFetchingIntervalHoursRareNtpUser));
106 108
107 double default_value_hours = 0.0; 109 double default_value_hours = 0.0;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 persistent_scheduler_(persistent_scheduler), 186 persistent_scheduler_(persistent_scheduler),
185 background_fetch_in_progress_(false), 187 background_fetch_in_progress_(false),
186 user_classifier_(user_classifier), 188 user_classifier_(user_classifier),
187 pref_service_(pref_service), 189 pref_service_(pref_service),
188 clock_(std::move(clock)), 190 clock_(std::move(clock)),
189 enabled_triggers_(GetEnabledTriggerTypes()) { 191 enabled_triggers_(GetEnabledTriggerTypes()) {
190 DCHECK(user_classifier); 192 DCHECK(user_classifier);
191 DCHECK(pref_service); 193 DCHECK(pref_service);
192 194
193 LoadLastFetchingSchedule(); 195 LoadLastFetchingSchedule();
194
195 provider_->SetProviderStatusCallback(
196 base::MakeUnique<RemoteSuggestionsProvider::ProviderStatusCallback>(
197 base::BindRepeating(
198 &SchedulingRemoteSuggestionsProvider::OnProviderStatusChanged,
199 base::Unretained(this))));
200 } 196 }
201 197
202 SchedulingRemoteSuggestionsProvider::~SchedulingRemoteSuggestionsProvider() = 198 SchedulingRemoteSuggestionsProvider::~SchedulingRemoteSuggestionsProvider() =
203 default; 199 default;
204 200
205 // static 201 // static
206 void SchedulingRemoteSuggestionsProvider::RegisterProfilePrefs( 202 void SchedulingRemoteSuggestionsProvider::RegisterProfilePrefs(
207 PrefRegistrySimple* registry) { 203 PrefRegistrySimple* registry) {
208 registry->RegisterInt64Pref(prefs::kSnippetPersistentFetchingIntervalWifi, 0); 204 registry->RegisterInt64Pref(prefs::kSnippetPersistentFetchingIntervalWifi, 0);
209 registry->RegisterInt64Pref(prefs::kSnippetPersistentFetchingIntervalFallback, 205 registry->RegisterInt64Pref(prefs::kSnippetPersistentFetchingIntervalFallback,
210 0); 206 0);
211 registry->RegisterInt64Pref(prefs::kSnippetSoftFetchingIntervalOnUsageEvent, 207 registry->RegisterInt64Pref(prefs::kSnippetSoftFetchingIntervalOnUsageEvent,
212 0); 208 0);
213 registry->RegisterInt64Pref(prefs::kSnippetLastFetchAttempt, 0); 209 registry->RegisterInt64Pref(prefs::kSnippetLastFetchAttempt, 0);
214 registry->RegisterInt64Pref(prefs::kSnippetSoftFetchingIntervalOnNtpOpened, 210 registry->RegisterInt64Pref(prefs::kSnippetSoftFetchingIntervalOnNtpOpened,
215 0); 211 0);
216 } 212 }
217 213
214 void SchedulingRemoteSuggestionsProvider::OnProviderActivated() {
215 StartScheduling();
216 }
217
218 void SchedulingRemoteSuggestionsProvider::OnProviderDeactivated() {
219 StopScheduling();
220 }
221
222 void SchedulingRemoteSuggestionsProvider::OnSuggestionsCleared() {
223 // There are no suggestions, be as eager to fetch as possible.
224 ClearLastFetchAttemptTime();
225 }
226
227 void SchedulingRemoteSuggestionsProvider::OnHistoryCleared() {
228 // Due to privacy, we should not fetch for a while (unless the user explicitly
229 // asks for new suggestions) to give sync the time to propagate the changes in
230 // history to the server.
231 background_fetches_allowed_after_ =
232 clock_->Now() + base::TimeDelta::FromMinutes(
233 kBlockBackgroundFetchesMinutesAfterClearingHistory);
234 // After that time elapses, we should fetch as soon as possible.
235 ClearLastFetchAttemptTime();
236 }
237
218 void SchedulingRemoteSuggestionsProvider::RescheduleFetching() { 238 void SchedulingRemoteSuggestionsProvider::RescheduleFetching() {
219 // Force the reschedule by stopping and starting it again. 239 // Force the reschedule by stopping and starting it again.
220 StopScheduling(); 240 StopScheduling();
221 StartScheduling(); 241 StartScheduling();
222 } 242 }
223 243
224 void SchedulingRemoteSuggestionsProvider::OnPersistentSchedulerWakeUp() { 244 void SchedulingRemoteSuggestionsProvider::OnPersistentSchedulerWakeUp() {
225 RefetchInTheBackgroundIfEnabled(TriggerType::PERSISTENT_SCHEDULER_WAKE_UP); 245 RefetchInTheBackgroundIfEnabled(TriggerType::PERSISTENT_SCHEDULER_WAKE_UP);
226 } 246 }
227 247
(...skipping 18 matching lines...) Expand all
246 } 266 }
247 267
248 void SchedulingRemoteSuggestionsProvider::OnNTPOpened() { 268 void SchedulingRemoteSuggestionsProvider::OnNTPOpened() {
249 if (!ShouldRefetchInTheBackgroundNow(TriggerType::NTP_OPENED)) { 269 if (!ShouldRefetchInTheBackgroundNow(TriggerType::NTP_OPENED)) {
250 return; 270 return;
251 } 271 }
252 272
253 RefetchInTheBackgroundIfEnabled(TriggerType::NTP_OPENED); 273 RefetchInTheBackgroundIfEnabled(TriggerType::NTP_OPENED);
254 } 274 }
255 275
256 void SchedulingRemoteSuggestionsProvider::SetProviderStatusCallback(
257 std::unique_ptr<ProviderStatusCallback> callback) {
258 provider_->SetProviderStatusCallback(std::move(callback));
259 }
260
261 void SchedulingRemoteSuggestionsProvider::RefetchInTheBackground( 276 void SchedulingRemoteSuggestionsProvider::RefetchInTheBackground(
262 std::unique_ptr<FetchStatusCallback> callback) { 277 std::unique_ptr<FetchStatusCallback> callback) {
263 if (background_fetch_in_progress_) { 278 if (background_fetch_in_progress_) {
264 if (callback) { 279 if (callback) {
265 callback->Run( 280 callback->Run(
266 Status(StatusCode::TEMPORARY_ERROR, "Background fetch in progress")); 281 Status(StatusCode::TEMPORARY_ERROR, "Background fetch in progress"));
267 } 282 }
268 return; 283 return;
269 } 284 }
270 285
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 Category category, 352 Category category,
338 const DismissedSuggestionsCallback& callback) { 353 const DismissedSuggestionsCallback& callback) {
339 provider_->GetDismissedSuggestionsForDebugging(category, callback); 354 provider_->GetDismissedSuggestionsForDebugging(category, callback);
340 } 355 }
341 356
342 void SchedulingRemoteSuggestionsProvider::ClearDismissedSuggestionsForDebugging( 357 void SchedulingRemoteSuggestionsProvider::ClearDismissedSuggestionsForDebugging(
343 Category category) { 358 Category category) {
344 provider_->ClearDismissedSuggestionsForDebugging(category); 359 provider_->ClearDismissedSuggestionsForDebugging(category);
345 } 360 }
346 361
347 void SchedulingRemoteSuggestionsProvider::OnProviderStatusChanged(
348 RemoteSuggestionsProvider::ProviderStatus status) {
349 switch (status) {
350 case RemoteSuggestionsProvider::ProviderStatus::ACTIVE:
351 StartScheduling();
352 return;
353 case RemoteSuggestionsProvider::ProviderStatus::INACTIVE:
354 StopScheduling();
355 return;
356 }
357 NOTREACHED();
358 }
359
360 void SchedulingRemoteSuggestionsProvider::StartScheduling() { 362 void SchedulingRemoteSuggestionsProvider::StartScheduling() {
361 FetchingSchedule new_schedule = GetDesiredFetchingSchedule(); 363 FetchingSchedule new_schedule = GetDesiredFetchingSchedule();
362 364
363 if (schedule_ == new_schedule) { 365 if (schedule_ == new_schedule) {
364 // Do not schedule if nothing has changed; 366 // Do not schedule if nothing has changed;
365 return; 367 return;
366 } 368 }
367 369
368 schedule_ = new_schedule; 370 schedule_ = new_schedule;
369 StoreFetchingSchedule(); 371 StoreFetchingSchedule();
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 case TriggerType::BROWSER_FOREGROUNDED: 464 case TriggerType::BROWSER_FOREGROUNDED:
463 case TriggerType::BROWSER_COLD_START: 465 case TriggerType::BROWSER_COLD_START:
464 first_allowed_fetch_time = 466 first_allowed_fetch_time =
465 last_fetch_attempt_time + schedule_.interval_soft_on_usage_event; 467 last_fetch_attempt_time + schedule_.interval_soft_on_usage_event;
466 break; 468 break;
467 case TriggerType::PERSISTENT_SCHEDULER_WAKE_UP: 469 case TriggerType::PERSISTENT_SCHEDULER_WAKE_UP:
468 case TriggerType::COUNT: 470 case TriggerType::COUNT:
469 NOTREACHED(); 471 NOTREACHED();
470 break; 472 break;
471 } 473 }
472 return first_allowed_fetch_time <= clock_->Now(); 474 base::Time now = clock_->Now();
475
476 return background_fetches_allowed_after_ <= now &&
477 first_allowed_fetch_time <= now;
473 } 478 }
474 479
475 bool SchedulingRemoteSuggestionsProvider::BackgroundFetchesDisabled( 480 bool SchedulingRemoteSuggestionsProvider::BackgroundFetchesDisabled(
476 SchedulingRemoteSuggestionsProvider::TriggerType trigger) const { 481 SchedulingRemoteSuggestionsProvider::TriggerType trigger) const {
477 if (schedule_.is_empty()) { 482 if (schedule_.is_empty()) {
478 return true; // Background fetches are disabled in general. 483 return true; // Background fetches are disabled in general.
479 } 484 }
480 485
481 if (enabled_triggers_.count(trigger) == 0) { 486 if (enabled_triggers_.count(trigger) == 0) {
482 return true; // Background fetches for |trigger| are not enabled. 487 return true; // Background fetches for |trigger| are not enabled.
(...skipping 29 matching lines...) Expand all
512 // Reschedule after a fetch. The persistent schedule is applied only after a 517 // Reschedule after a fetch. The persistent schedule is applied only after a
513 // successful fetch. After a failed fetch, we want to keep the previous 518 // successful fetch. After a failed fetch, we want to keep the previous
514 // persistent schedule intact so that we eventually get a persistent 519 // persistent schedule intact so that we eventually get a persistent
515 // fallback fetch (if the wifi persistent fetches keep failing). 520 // fallback fetch (if the wifi persistent fetches keep failing).
516 if (fetch_status.code != StatusCode::SUCCESS) { 521 if (fetch_status.code != StatusCode::SUCCESS) {
517 return; 522 return;
518 } 523 }
519 ApplyPersistentFetchingSchedule(); 524 ApplyPersistentFetchingSchedule();
520 } 525 }
521 526
527 void SchedulingRemoteSuggestionsProvider::ClearLastFetchAttemptTime() {
528 pref_service_->ClearPref(prefs::kSnippetLastFetchAttempt);
529 }
530
522 std::set<SchedulingRemoteSuggestionsProvider::TriggerType> 531 std::set<SchedulingRemoteSuggestionsProvider::TriggerType>
523 SchedulingRemoteSuggestionsProvider::GetEnabledTriggerTypes() { 532 SchedulingRemoteSuggestionsProvider::GetEnabledTriggerTypes() {
524 static_assert(static_cast<unsigned int>(TriggerType::COUNT) == 533 static_assert(static_cast<unsigned int>(TriggerType::COUNT) ==
525 arraysize(kTriggerTypeNames), 534 arraysize(kTriggerTypeNames),
526 "Fill in names for trigger types."); 535 "Fill in names for trigger types.");
527 536
528 std::string param_value = base::GetFieldTrialParamValueByFeature( 537 std::string param_value = base::GetFieldTrialParamValueByFeature(
529 ntp_snippets::kArticleSuggestionsFeature, kTriggerTypesParamName); 538 ntp_snippets::kArticleSuggestionsFeature, kTriggerTypesParamName);
530 if (param_value == kTriggerTypesParamValueForEmptyList) { 539 if (param_value == kTriggerTypesParamValueForEmptyList) {
531 return std::set<TriggerType>(); 540 return std::set<TriggerType>();
(...skipping 26 matching lines...) Expand all
558 return enabled_types; 567 return enabled_types;
559 } 568 }
560 569
561 std::set<SchedulingRemoteSuggestionsProvider::TriggerType> 570 std::set<SchedulingRemoteSuggestionsProvider::TriggerType>
562 SchedulingRemoteSuggestionsProvider::GetDefaultEnabledTriggerTypes() { 571 SchedulingRemoteSuggestionsProvider::GetDefaultEnabledTriggerTypes() {
563 return {TriggerType::PERSISTENT_SCHEDULER_WAKE_UP, TriggerType::NTP_OPENED, 572 return {TriggerType::PERSISTENT_SCHEDULER_WAKE_UP, TriggerType::NTP_OPENED,
564 TriggerType::BROWSER_FOREGROUNDED}; 573 TriggerType::BROWSER_FOREGROUNDED};
565 } 574 }
566 575
567 } // namespace ntp_snippets 576 } // namespace ntp_snippets
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698