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

Side by Side Diff: sync/engine/sync_scheduler_impl.cc

Issue 14963002: sync: Report GetUpdate triggers to the server (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update tests Created 7 years, 7 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "sync/engine/sync_scheduler_impl.h" 5 #include "sync/engine/sync_scheduler_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cstring> 8 #include <cstring>
9 9
10 #include "base/auto_reset.h" 10 #include "base/auto_reset.h"
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 started_ = true; 220 started_ = true;
221 SendInitialSnapshot(); 221 SendInitialSnapshot();
222 } 222 }
223 223
224 DCHECK(!session_context_->account_name().empty()); 224 DCHECK(!session_context_->account_name().empty());
225 DCHECK(syncer_.get()); 225 DCHECK(syncer_.get());
226 Mode old_mode = mode_; 226 Mode old_mode = mode_;
227 mode_ = mode; 227 mode_ = mode;
228 AdjustPolling(UPDATE_INTERVAL); // Will kick start poll timer if needed. 228 AdjustPolling(UPDATE_INTERVAL); // Will kick start poll timer if needed.
229 229
230 if (old_mode != mode_ && mode_ == NORMAL_MODE && !nudge_tracker_.IsEmpty()) { 230 if (old_mode != mode_ && mode_ == NORMAL_MODE &&
231 nudge_tracker_.SyncRequired()) {
231 // We just got back to normal mode. Let's try to run the work that was 232 // We just got back to normal mode. Let's try to run the work that was
232 // queued up while we were configuring. 233 // queued up while we were configuring.
233 DoNudgeSyncSessionJob(NORMAL_PRIORITY); 234 DoNudgeSyncSessionJob(NORMAL_PRIORITY);
234 } 235 }
235 } 236 }
236 237
237 void SyncSchedulerImpl::SendInitialSnapshot() { 238 void SyncSchedulerImpl::SendInitialSnapshot() {
238 DCHECK(CalledOnValidThread()); 239 DCHECK(CalledOnValidThread());
239 scoped_ptr<SyncSession> dummy(new SyncSession( 240 scoped_ptr<SyncSession> dummy(new SyncSession(
240 session_context_, this, SyncSourceInfo())); 241 session_context_, this, SyncSourceInfo()));
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 } 348 }
348 349
349 if (mode_ == CONFIGURATION_MODE) { 350 if (mode_ == CONFIGURATION_MODE) {
350 SDVLOG(1) << "Not running nudge because we're in configuration mode."; 351 SDVLOG(1) << "Not running nudge because we're in configuration mode.";
351 return false; 352 return false;
352 } 353 }
353 354
354 return true; 355 return true;
355 } 356 }
356 357
357 void SyncSchedulerImpl::ScheduleNudgeAsync( 358 void SyncSchedulerImpl::ScheduleLocalNudge(
358 const TimeDelta& desired_delay, 359 const TimeDelta& desired_delay,
359 NudgeSource source, ModelTypeSet types, 360 ModelTypeSet types,
360 const tracked_objects::Location& nudge_location) { 361 const tracked_objects::Location& nudge_location) {
361 DCHECK(CalledOnValidThread()); 362 DCHECK(CalledOnValidThread());
363 DCHECK(!types.Empty());
364
362 SDVLOG_LOC(nudge_location, 2) 365 SDVLOG_LOC(nudge_location, 2)
363 << "Nudge scheduled with delay " 366 << "Scheduling sync because of local change to "
364 << desired_delay.InMilliseconds() << " ms, " 367 << ModelTypeSetToString(types);
365 << "source " << GetNudgeSourceString(source) << ", " 368 UpdateNudgeTimeRecords(types);
366 << "types " << ModelTypeSetToString(types); 369 nudge_tracker_.RecordLocalChange(types);
367 370 ScheduleNudgeImpl(desired_delay, nudge_location);
368 ModelTypeInvalidationMap invalidation_map =
369 ModelTypeSetToInvalidationMap(types, std::string());
370 SyncSchedulerImpl::ScheduleNudgeImpl(desired_delay,
371 GetUpdatesFromNudgeSource(source),
372 invalidation_map,
373 nudge_location);
374 } 371 }
375 372
376 void SyncSchedulerImpl::ScheduleNudgeWithStatesAsync( 373 void SyncSchedulerImpl::ScheduleLocalRefreshRequest(
377 const TimeDelta& desired_delay, 374 const TimeDelta& desired_delay,
378 NudgeSource source, const ModelTypeInvalidationMap& invalidation_map, 375 ModelTypeSet types,
379 const tracked_objects::Location& nudge_location) { 376 const tracked_objects::Location& nudge_location) {
380 DCHECK(CalledOnValidThread()); 377 DCHECK(CalledOnValidThread());
378 DCHECK(!types.Empty());
379
381 SDVLOG_LOC(nudge_location, 2) 380 SDVLOG_LOC(nudge_location, 2)
382 << "Nudge scheduled with delay " 381 << "Scheduling sync because of local refresch request for "
383 << desired_delay.InMilliseconds() << " ms, " 382 << ModelTypeSetToString(types);
384 << "source " << GetNudgeSourceString(source) << ", " 383 nudge_tracker_.RecordLocalRefreshRequest(types);
385 << "payloads " 384 ScheduleNudgeImpl(desired_delay, nudge_location);
386 << ModelTypeInvalidationMapToString(invalidation_map);
387
388 SyncSchedulerImpl::ScheduleNudgeImpl(desired_delay,
389 GetUpdatesFromNudgeSource(source),
390 invalidation_map,
391 nudge_location);
392 } 385 }
393 386
387 void SyncSchedulerImpl::ScheduleInvalidation(
tim (not reviewing) 2013/05/06 21:29:04 ScheduleInvalidationNudge seems better, to disting
rlarocque 2013/05/07 18:45:39 Done.
388 const TimeDelta& desired_delay,
389 const ModelTypeInvalidationMap& invalidation_map,
390 const tracked_objects::Location& nudge_location) {
391 DCHECK(CalledOnValidThread());
392 DCHECK(!invalidation_map.empty());
393
394 SDVLOG_LOC(nudge_location, 2)
395 << "Scheduling sync because we received invalidation for "
396 << ModelTypeInvalidationMapToString(invalidation_map);
397 nudge_tracker_.RecordRemoteInvalidation(invalidation_map);
398 ScheduleNudgeImpl(desired_delay, nudge_location);
399 }
394 400
395 // TODO(zea): Consider adding separate throttling/backoff for datatype 401 // TODO(zea): Consider adding separate throttling/backoff for datatype
396 // refresh requests. 402 // refresh requests.
397 void SyncSchedulerImpl::ScheduleNudgeImpl( 403 void SyncSchedulerImpl::ScheduleNudgeImpl(
398 const TimeDelta& delay, 404 const TimeDelta& delay,
399 GetUpdatesCallerInfo::GetUpdatesSource source,
400 const ModelTypeInvalidationMap& invalidation_map,
401 const tracked_objects::Location& nudge_location) { 405 const tracked_objects::Location& nudge_location) {
402 DCHECK(CalledOnValidThread()); 406 DCHECK(CalledOnValidThread());
403 DCHECK(!invalidation_map.empty()) << "Nudge scheduled for no types!";
404 407
405 if (no_scheduling_allowed_) { 408 if (no_scheduling_allowed_) {
406 NOTREACHED() << "Illegal to schedule job while session in progress."; 409 NOTREACHED() << "Illegal to schedule job while session in progress.";
407 return; 410 return;
408 } 411 }
409 412
410 if (!started_) { 413 if (!started_) {
411 SDVLOG_LOC(nudge_location, 2) 414 SDVLOG_LOC(nudge_location, 2)
412 << "Dropping nudge, scheduler is not running."; 415 << "Dropping nudge, scheduler is not running.";
413 return; 416 return;
414 } 417 }
415 418
416 SDVLOG_LOC(nudge_location, 2) 419 SDVLOG_LOC(nudge_location, 2)
417 << "In ScheduleNudgeImpl with delay " 420 << "In ScheduleNudgeImpl with delay "
418 << delay.InMilliseconds() << " ms, " 421 << delay.InMilliseconds() << " ms";
419 << "source " << GetUpdatesSourceString(source) << ", "
420 << "payloads "
421 << ModelTypeInvalidationMapToString(invalidation_map);
422
423 SyncSourceInfo info(source, invalidation_map);
424 UpdateNudgeTimeRecords(info);
425
426 // Coalesce the new nudge information with any existing information.
427 nudge_tracker_.CoalesceSources(info);
428 422
429 if (!CanRunNudgeJobNow(NORMAL_PRIORITY)) 423 if (!CanRunNudgeJobNow(NORMAL_PRIORITY))
430 return; 424 return;
431 425
432 if (!started_) { 426 if (!started_) {
433 SDVLOG_LOC(nudge_location, 2) 427 SDVLOG_LOC(nudge_location, 2)
434 << "Schedule not started; not running a nudge."; 428 << "Schedule not started; not running a nudge.";
435 return; 429 return;
436 } 430 }
437 431
(...skipping 28 matching lines...) Expand all
466 } 460 }
467 461
468 void SyncSchedulerImpl::DoNudgeSyncSessionJob(JobPriority priority) { 462 void SyncSchedulerImpl::DoNudgeSyncSessionJob(JobPriority priority) {
469 DCHECK(CalledOnValidThread()); 463 DCHECK(CalledOnValidThread());
470 464
471 if (!CanRunNudgeJobNow(priority)) 465 if (!CanRunNudgeJobNow(priority))
472 return; 466 return;
473 467
474 DVLOG(2) << "Will run normal mode sync cycle with routing info " 468 DVLOG(2) << "Will run normal mode sync cycle with routing info "
475 << ModelSafeRoutingInfoToString(session_context_->routing_info()); 469 << ModelSafeRoutingInfoToString(session_context_->routing_info());
476 SyncSession session(session_context_, this, nudge_tracker_.source_info()); 470 SyncSession session(session_context_,
471 this,
472 nudge_tracker_.source_info(),
473 &nudge_tracker_);
477 bool premature_exit = !syncer_->SyncShare(&session, SYNCER_BEGIN, SYNCER_END); 474 bool premature_exit = !syncer_->SyncShare(&session, SYNCER_BEGIN, SYNCER_END);
478 AdjustPolling(FORCE_RESET); 475 AdjustPolling(FORCE_RESET);
479 476
480 bool success = !premature_exit 477 bool success = !premature_exit
481 && !sessions::HasSyncerError( 478 && !sessions::HasSyncerError(
482 session.status_controller().model_neutral_state()); 479 session.status_controller().model_neutral_state());
483 480
484 if (success) { 481 if (success) {
485 // That cycle took care of any outstanding work we had. 482 // That cycle took care of any outstanding work we had.
486 SDVLOG(2) << "Nudge succeeded."; 483 SDVLOG(2) << "Nudge succeeded.";
487 nudge_tracker_.Reset(); 484 nudge_tracker_.RecordSuccessfulSyncCycle();
488 scheduled_nudge_time_ = base::TimeTicks(); 485 scheduled_nudge_time_ = base::TimeTicks();
489 486
490 // If we're here, then we successfully reached the server. End all backoff. 487 // If we're here, then we successfully reached the server. End all backoff.
491 wait_interval_.reset(); 488 wait_interval_.reset();
492 NotifyRetryTime(base::Time()); 489 NotifyRetryTime(base::Time());
493 return; 490 return;
494 } else { 491 } else {
495 HandleFailure(session.status_controller().model_neutral_state()); 492 HandleFailure(session.status_controller().model_neutral_state());
496 } 493 }
497 } 494 }
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 AdjustPolling(UPDATE_INTERVAL); 571 AdjustPolling(UPDATE_INTERVAL);
575 572
576 if (IsSyncingCurrentlySilenced()) { 573 if (IsSyncingCurrentlySilenced()) {
577 SDVLOG(2) << "Poll request got us throttled."; 574 SDVLOG(2) << "Poll request got us throttled.";
578 // The OnSilencedUntil() call set up the WaitInterval for us. All we need 575 // The OnSilencedUntil() call set up the WaitInterval for us. All we need
579 // to do is start the timer. 576 // to do is start the timer.
580 RestartWaiting(); 577 RestartWaiting();
581 } 578 }
582 } 579 }
583 580
584 void SyncSchedulerImpl::UpdateNudgeTimeRecords(const SyncSourceInfo& info) { 581 void SyncSchedulerImpl::UpdateNudgeTimeRecords(ModelTypeSet types) {
585 DCHECK(CalledOnValidThread()); 582 DCHECK(CalledOnValidThread());
586
587 // We are interested in recording time between local nudges for datatypes.
588 // TODO(tim): Consider tracking LOCAL_NOTIFICATION as well.
589 if (info.updates_source != GetUpdatesCallerInfo::LOCAL)
590 return;
591
592 base::TimeTicks now = TimeTicks::Now(); 583 base::TimeTicks now = TimeTicks::Now();
593 // Update timing information for how often datatypes are triggering nudges. 584 // Update timing information for how often datatypes are triggering nudges.
594 for (ModelTypeInvalidationMap::const_iterator iter = info.types.begin(); 585 for (ModelTypeSet::Iterator iter = types.First(); iter.Good(); iter.Inc()) {
595 iter != info.types.end(); 586 base::TimeTicks previous = last_local_nudges_by_model_type_[iter.Get()];
596 ++iter) { 587 last_local_nudges_by_model_type_[iter.Get()] = now;
597 base::TimeTicks previous = last_local_nudges_by_model_type_[iter->first];
598 last_local_nudges_by_model_type_[iter->first] = now;
599 if (previous.is_null()) 588 if (previous.is_null())
600 continue; 589 continue;
601 590
602 #define PER_DATA_TYPE_MACRO(type_str) \ 591 #define PER_DATA_TYPE_MACRO(type_str) \
603 SYNC_FREQ_HISTOGRAM("Sync.Freq" type_str, now - previous); 592 SYNC_FREQ_HISTOGRAM("Sync.Freq" type_str, now - previous);
604 SYNC_DATA_TYPE_HISTOGRAM(iter->first); 593 SYNC_DATA_TYPE_HISTOGRAM(iter.Get());
605 #undef PER_DATA_TYPE_MACRO 594 #undef PER_DATA_TYPE_MACRO
606 } 595 }
607 } 596 }
608 597
609 void SyncSchedulerImpl::AdjustPolling(PollAdjustType type) { 598 void SyncSchedulerImpl::AdjustPolling(PollAdjustType type) {
610 DCHECK(CalledOnValidThread()); 599 DCHECK(CalledOnValidThread());
611 600
612 TimeDelta poll = (!session_context_->notifications_enabled()) ? 601 TimeDelta poll = (!session_context_->notifications_enabled()) ?
613 syncer_short_poll_interval_seconds_ : 602 syncer_short_poll_interval_seconds_ :
614 syncer_long_poll_interval_seconds_; 603 syncer_long_poll_interval_seconds_;
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 } 675 }
687 676
688 // This is the only place where we invoke DoSyncSessionJob with canary 677 // This is the only place where we invoke DoSyncSessionJob with canary
689 // privileges. Everyone else should use NORMAL_PRIORITY. 678 // privileges. Everyone else should use NORMAL_PRIORITY.
690 void SyncSchedulerImpl::TryCanaryJob() { 679 void SyncSchedulerImpl::TryCanaryJob() {
691 DCHECK(CalledOnValidThread()); 680 DCHECK(CalledOnValidThread());
692 681
693 if (mode_ == CONFIGURATION_MODE && pending_configure_params_) { 682 if (mode_ == CONFIGURATION_MODE && pending_configure_params_) {
694 SDVLOG(2) << "Found pending configure job; will run as canary"; 683 SDVLOG(2) << "Found pending configure job; will run as canary";
695 DoConfigurationSyncSessionJob(CANARY_PRIORITY); 684 DoConfigurationSyncSessionJob(CANARY_PRIORITY);
696 } else if (mode_ == NORMAL_MODE && !nudge_tracker_.IsEmpty()) { 685 } else if (mode_ == NORMAL_MODE && nudge_tracker_.SyncRequired()) {
tim (not reviewing) 2013/05/06 21:29:04 Tangential question, would NORMAL_MODE be better r
rlarocque 2013/05/07 18:45:39 I actually like the name NORMAL_MODE. I think it
tim (not reviewing) 2013/05/07 20:34:13 Fair, I like NORMAL_MODE as well.
697 SDVLOG(2) << "Found pending nudge job; will run as canary"; 686 SDVLOG(2) << "Found pending nudge job; will run as canary";
698 DoNudgeSyncSessionJob(CANARY_PRIORITY); 687 DoNudgeSyncSessionJob(CANARY_PRIORITY);
699 } else { 688 } else {
700 SDVLOG(2) << "Found no work to do; will not run a canary"; 689 SDVLOG(2) << "Found no work to do; will not run a canary";
701 } 690 }
702 } 691 }
703 692
704 void SyncSchedulerImpl::PollTimerCallback() { 693 void SyncSchedulerImpl::PollTimerCallback() {
705 DCHECK(CalledOnValidThread()); 694 DCHECK(CalledOnValidThread());
706 if (no_scheduling_allowed_) { 695 if (no_scheduling_allowed_) {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 SDVLOG(2) << "Sync Scheduler requesting early exit."; 795 SDVLOG(2) << "Sync Scheduler requesting early exit.";
807 syncer_->RequestEarlyExit(); // Thread-safe. 796 syncer_->RequestEarlyExit(); // Thread-safe.
808 } 797 }
809 if (IsActionableError(snapshot.model_neutral_state().sync_protocol_error)) 798 if (IsActionableError(snapshot.model_neutral_state().sync_protocol_error))
810 OnActionableError(snapshot); 799 OnActionableError(snapshot);
811 } 800 }
812 801
813 void SyncSchedulerImpl::SetNotificationsEnabled(bool notifications_enabled) { 802 void SyncSchedulerImpl::SetNotificationsEnabled(bool notifications_enabled) {
814 DCHECK(CalledOnValidThread()); 803 DCHECK(CalledOnValidThread());
815 session_context_->set_notifications_enabled(notifications_enabled); 804 session_context_->set_notifications_enabled(notifications_enabled);
805 if (notifications_enabled) {
806 nudge_tracker_.InvalidationsEnabled();
807 } else {
808 nudge_tracker_.InvalidationsDisabled();
809 }
816 } 810 }
817 811
818 base::TimeDelta SyncSchedulerImpl::GetSessionsCommitDelay() const { 812 base::TimeDelta SyncSchedulerImpl::GetSessionsCommitDelay() const {
819 DCHECK(CalledOnValidThread()); 813 DCHECK(CalledOnValidThread());
820 return sessions_commit_delay_; 814 return sessions_commit_delay_;
821 } 815 }
822 816
823 #undef SDVLOG_LOC 817 #undef SDVLOG_LOC
824 818
825 #undef SDVLOG 819 #undef SDVLOG
826 820
827 #undef SLOG 821 #undef SLOG
828 822
829 #undef ENUM_CASE 823 #undef ENUM_CASE
830 824
831 } // namespace syncer 825 } // namespace syncer
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698