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

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: Tim's comments #3 Created 3 years, 10 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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 196
195 provider_->SetProviderStatusCallback( 197 provider_->SetRemoteSuggestionsScheduler(this);
Marc Treib 2017/02/23 13:52:24 This is a bit weird: We now have two-way linking b
jkrcal 2017/02/24 09:21:43 Added a bug and TODOs (after an offline discussion
196 base::MakeUnique<RemoteSuggestionsProvider::ProviderStatusCallback>(
197 base::BindRepeating(
198 &SchedulingRemoteSuggestionsProvider::OnProviderStatusChanged,
199 base::Unretained(this))));
200 } 198 }
201 199
202 SchedulingRemoteSuggestionsProvider::~SchedulingRemoteSuggestionsProvider() = 200 SchedulingRemoteSuggestionsProvider::~SchedulingRemoteSuggestionsProvider() =
203 default; 201 default;
204 202
205 // static 203 // static
206 void SchedulingRemoteSuggestionsProvider::RegisterProfilePrefs( 204 void SchedulingRemoteSuggestionsProvider::RegisterProfilePrefs(
207 PrefRegistrySimple* registry) { 205 PrefRegistrySimple* registry) {
208 registry->RegisterInt64Pref(prefs::kSnippetPersistentFetchingIntervalWifi, 0); 206 registry->RegisterInt64Pref(prefs::kSnippetPersistentFetchingIntervalWifi, 0);
209 registry->RegisterInt64Pref(prefs::kSnippetPersistentFetchingIntervalFallback, 207 registry->RegisterInt64Pref(prefs::kSnippetPersistentFetchingIntervalFallback,
210 0); 208 0);
211 registry->RegisterInt64Pref(prefs::kSnippetSoftFetchingIntervalOnUsageEvent, 209 registry->RegisterInt64Pref(prefs::kSnippetSoftFetchingIntervalOnUsageEvent,
212 0); 210 0);
213 registry->RegisterInt64Pref(prefs::kSnippetLastFetchAttempt, 0); 211 registry->RegisterInt64Pref(prefs::kSnippetLastFetchAttempt, 0);
214 registry->RegisterInt64Pref(prefs::kSnippetSoftFetchingIntervalOnNtpOpened, 212 registry->RegisterInt64Pref(prefs::kSnippetSoftFetchingIntervalOnNtpOpened,
215 0); 213 0);
216 } 214 }
217 215
216 void SchedulingRemoteSuggestionsProvider::OnProviderActivated() {
217 StartScheduling();
218 }
219
220 void SchedulingRemoteSuggestionsProvider::OnProviderInactivated() {
221 StopScheduling();
222 }
223
224 void SchedulingRemoteSuggestionsProvider::OnSuggestionsCleared() {
225 // There are no suggestions, be as eager to fetch as possible.
226 ClearLastFetchAttemptTime();
227 }
228
229 void SchedulingRemoteSuggestionsProvider::OnHistoryCleared() {
230 // Due to privacy, we should not fetch for a while (unless the user explicitly
231 // asks for new suggestions) do give sync the time to propagate the changes in
Marc Treib 2017/02/23 13:52:24 s/do/to/
jkrcal 2017/02/24 09:21:43 Done.
232 // history to the server.
233 background_fetches_allowed_after_ =
234 clock_->Now() +
235 base::TimeDelta::FromMinutes(
236 kBlockBackgroundFetchesMinutesAfterClearingHistory);
237 // After that time elapses, we should fetch as soon as possible.
238 ClearLastFetchAttemptTime();
239 }
240
218 void SchedulingRemoteSuggestionsProvider::RescheduleFetching() { 241 void SchedulingRemoteSuggestionsProvider::RescheduleFetching() {
219 // Force the reschedule by stopping and starting it again. 242 // Force the reschedule by stopping and starting it again.
220 StopScheduling(); 243 StopScheduling();
221 StartScheduling(); 244 StartScheduling();
222 } 245 }
223 246
224 void SchedulingRemoteSuggestionsProvider::OnPersistentSchedulerWakeUp() { 247 void SchedulingRemoteSuggestionsProvider::OnPersistentSchedulerWakeUp() {
225 RefetchInTheBackgroundIfEnabled(TriggerType::PERSISTENT_SCHEDULER_WAKE_UP); 248 RefetchInTheBackgroundIfEnabled(TriggerType::PERSISTENT_SCHEDULER_WAKE_UP);
226 } 249 }
227 250
(...skipping 18 matching lines...) Expand all
246 } 269 }
247 270
248 void SchedulingRemoteSuggestionsProvider::OnNTPOpened() { 271 void SchedulingRemoteSuggestionsProvider::OnNTPOpened() {
249 if (!ShouldRefetchInTheBackgroundNow(TriggerType::NTP_OPENED)) { 272 if (!ShouldRefetchInTheBackgroundNow(TriggerType::NTP_OPENED)) {
250 return; 273 return;
251 } 274 }
252 275
253 RefetchInTheBackgroundIfEnabled(TriggerType::NTP_OPENED); 276 RefetchInTheBackgroundIfEnabled(TriggerType::NTP_OPENED);
254 } 277 }
255 278
256 void SchedulingRemoteSuggestionsProvider::SetProviderStatusCallback( 279 void SchedulingRemoteSuggestionsProvider::SetRemoteSuggestionsScheduler(
Marc Treib 2017/02/23 13:52:24 Can this method ever be called (on this particular
jkrcal 2017/02/24 09:21:43 Replaced by NOTREACHED()
257 std::unique_ptr<ProviderStatusCallback> callback) { 280 RemoteSuggestionsScheduler* scheduler) {
258 provider_->SetProviderStatusCallback(std::move(callback)); 281 provider_->SetRemoteSuggestionsScheduler(scheduler);
259 } 282 }
260 283
261 void SchedulingRemoteSuggestionsProvider::RefetchInTheBackground( 284 void SchedulingRemoteSuggestionsProvider::RefetchInTheBackground(
262 std::unique_ptr<FetchStatusCallback> callback) { 285 std::unique_ptr<FetchStatusCallback> callback) {
263 if (background_fetch_in_progress_) { 286 if (background_fetch_in_progress_) {
264 if (callback) { 287 if (callback) {
265 callback->Run( 288 callback->Run(
266 Status(StatusCode::TEMPORARY_ERROR, "Background fetch in progress")); 289 Status(StatusCode::TEMPORARY_ERROR, "Background fetch in progress"));
267 } 290 }
268 return; 291 return;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 Category category, 360 Category category,
338 const DismissedSuggestionsCallback& callback) { 361 const DismissedSuggestionsCallback& callback) {
339 provider_->GetDismissedSuggestionsForDebugging(category, callback); 362 provider_->GetDismissedSuggestionsForDebugging(category, callback);
340 } 363 }
341 364
342 void SchedulingRemoteSuggestionsProvider::ClearDismissedSuggestionsForDebugging( 365 void SchedulingRemoteSuggestionsProvider::ClearDismissedSuggestionsForDebugging(
343 Category category) { 366 Category category) {
344 provider_->ClearDismissedSuggestionsForDebugging(category); 367 provider_->ClearDismissedSuggestionsForDebugging(category);
345 } 368 }
346 369
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() { 370 void SchedulingRemoteSuggestionsProvider::StartScheduling() {
361 FetchingSchedule new_schedule = GetDesiredFetchingSchedule(); 371 FetchingSchedule new_schedule = GetDesiredFetchingSchedule();
362 372
363 if (schedule_ == new_schedule) { 373 if (schedule_ == new_schedule) {
364 // Do not schedule if nothing has changed; 374 // Do not schedule if nothing has changed;
365 return; 375 return;
366 } 376 }
367 377
368 schedule_ = new_schedule; 378 schedule_ = new_schedule;
369 StoreFetchingSchedule(); 379 StoreFetchingSchedule();
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 case TriggerType::BROWSER_FOREGROUNDED: 472 case TriggerType::BROWSER_FOREGROUNDED:
463 case TriggerType::BROWSER_COLD_START: 473 case TriggerType::BROWSER_COLD_START:
464 first_allowed_fetch_time = 474 first_allowed_fetch_time =
465 last_fetch_attempt_time + schedule_.interval_soft_on_usage_event; 475 last_fetch_attempt_time + schedule_.interval_soft_on_usage_event;
466 break; 476 break;
467 case TriggerType::PERSISTENT_SCHEDULER_WAKE_UP: 477 case TriggerType::PERSISTENT_SCHEDULER_WAKE_UP:
468 case TriggerType::COUNT: 478 case TriggerType::COUNT:
469 NOTREACHED(); 479 NOTREACHED();
470 break; 480 break;
471 } 481 }
472 return first_allowed_fetch_time <= clock_->Now(); 482 base::Time now = clock_->Now();
483
484 return background_fetches_allowed_after_ <= now &&
485 first_allowed_fetch_time <= now;
473 } 486 }
474 487
475 bool SchedulingRemoteSuggestionsProvider::BackgroundFetchesDisabled( 488 bool SchedulingRemoteSuggestionsProvider::BackgroundFetchesDisabled(
476 SchedulingRemoteSuggestionsProvider::TriggerType trigger) const { 489 SchedulingRemoteSuggestionsProvider::TriggerType trigger) const {
477 if (schedule_.is_empty()) { 490 if (schedule_.is_empty()) {
478 return true; // Background fetches are disabled in general. 491 return true; // Background fetches are disabled in general.
479 } 492 }
480 493
481 if (enabled_triggers_.count(trigger) == 0) { 494 if (enabled_triggers_.count(trigger) == 0) {
482 return true; // Background fetches for |trigger| are not enabled. 495 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 525 // 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 526 // successful fetch. After a failed fetch, we want to keep the previous
514 // persistent schedule intact so that we eventually get a persistent 527 // persistent schedule intact so that we eventually get a persistent
515 // fallback fetch (if the wifi persistent fetches keep failing). 528 // fallback fetch (if the wifi persistent fetches keep failing).
516 if (fetch_status.code != StatusCode::SUCCESS) { 529 if (fetch_status.code != StatusCode::SUCCESS) {
517 return; 530 return;
518 } 531 }
519 ApplyPersistentFetchingSchedule(); 532 ApplyPersistentFetchingSchedule();
520 } 533 }
521 534
535 void SchedulingRemoteSuggestionsProvider::ClearLastFetchAttemptTime() {
536 pref_service_->ClearPref(prefs::kSnippetLastFetchAttempt);
537 }
538
522 std::set<SchedulingRemoteSuggestionsProvider::TriggerType> 539 std::set<SchedulingRemoteSuggestionsProvider::TriggerType>
523 SchedulingRemoteSuggestionsProvider::GetEnabledTriggerTypes() { 540 SchedulingRemoteSuggestionsProvider::GetEnabledTriggerTypes() {
524 static_assert(static_cast<unsigned int>(TriggerType::COUNT) == 541 static_assert(static_cast<unsigned int>(TriggerType::COUNT) ==
525 arraysize(kTriggerTypeNames), 542 arraysize(kTriggerTypeNames),
526 "Fill in names for trigger types."); 543 "Fill in names for trigger types.");
527 544
528 std::string param_value = base::GetFieldTrialParamValueByFeature( 545 std::string param_value = base::GetFieldTrialParamValueByFeature(
529 ntp_snippets::kArticleSuggestionsFeature, kTriggerTypesParamName); 546 ntp_snippets::kArticleSuggestionsFeature, kTriggerTypesParamName);
530 if (param_value == kTriggerTypesParamValueForEmptyList) { 547 if (param_value == kTriggerTypesParamValueForEmptyList) {
531 return std::set<TriggerType>(); 548 return std::set<TriggerType>();
(...skipping 26 matching lines...) Expand all
558 return enabled_types; 575 return enabled_types;
559 } 576 }
560 577
561 std::set<SchedulingRemoteSuggestionsProvider::TriggerType> 578 std::set<SchedulingRemoteSuggestionsProvider::TriggerType>
562 SchedulingRemoteSuggestionsProvider::GetDefaultEnabledTriggerTypes() { 579 SchedulingRemoteSuggestionsProvider::GetDefaultEnabledTriggerTypes() {
563 return {TriggerType::PERSISTENT_SCHEDULER_WAKE_UP, TriggerType::NTP_OPENED, 580 return {TriggerType::PERSISTENT_SCHEDULER_WAKE_UP, TriggerType::NTP_OPENED,
564 TriggerType::BROWSER_FOREGROUNDED}; 581 TriggerType::BROWSER_FOREGROUNDED};
565 } 582 }
566 583
567 } // namespace ntp_snippets 584 } // namespace ntp_snippets
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698