This source file includes following definitions.
- invalidations_out_of_sync_
- IsSyncRequired
- IsGetUpdatesRequired
- IsRetryRequired
- RecordSuccessfulSyncCycle
- RecordLocalChange
- RecordLocalRefreshRequest
- RecordRemoteInvalidation
- OnInvalidationsEnabled
- OnInvalidationsDisabled
- SetTypesThrottledUntil
- UpdateTypeThrottlingState
- IsAnyTypeThrottled
- IsTypeThrottled
- GetTimeUntilNextUnthrottle
- GetThrottledTypes
- GetNudgedTypes
- GetNotifiedTypes
- GetRefreshRequestedTypes
- SetLegacyNotificationHint
- GetLegacySource
- FillProtoMessage
- SetSyncCycleStartTime
- SetHintBufferSize
- SetNextRetryTime
#include "sync/sessions/nudge_tracker.h"
#include "base/basictypes.h"
#include "sync/internal_api/public/base/invalidation.h"
#include "sync/notifier/invalidation_util.h"
#include "sync/notifier/object_id_invalidation_map.h"
#include "sync/protocol/sync.pb.h"
namespace syncer {
namespace sessions {
size_t NudgeTracker::kDefaultMaxPayloadsPerType = 10;
NudgeTracker::NudgeTracker()
: invalidations_enabled_(false),
invalidations_out_of_sync_(true) {
ModelTypeSet protocol_types = ProtocolTypes();
for (ModelTypeSet::Iterator it = protocol_types.First(); it.Good();
it.Inc()) {
invalidation::ObjectId id;
if (!RealModelTypeToObjectId(it.Get(), &id)) {
NOTREACHED();
} else {
type_trackers_.insert(std::make_pair(it.Get(), DataTypeTracker(id)));
}
}
}
NudgeTracker::~NudgeTracker() { }
bool NudgeTracker::IsSyncRequired() const {
if (IsRetryRequired())
return true;
for (TypeTrackerMap::const_iterator it = type_trackers_.begin();
it != type_trackers_.end(); ++it) {
if (it->second.IsSyncRequired()) {
return true;
}
}
return false;
}
bool NudgeTracker::IsGetUpdatesRequired() const {
if (invalidations_out_of_sync_)
return true;
if (IsRetryRequired())
return true;
for (TypeTrackerMap::const_iterator it = type_trackers_.begin();
it != type_trackers_.end(); ++it) {
if (it->second.IsGetUpdatesRequired()) {
return true;
}
}
return false;
}
bool NudgeTracker::IsRetryRequired() const {
if (sync_cycle_start_time_.is_null())
return false;
if (current_retry_time_.is_null())
return false;
return current_retry_time_ < sync_cycle_start_time_;
}
void NudgeTracker::RecordSuccessfulSyncCycle() {
if (IsRetryRequired())
current_retry_time_ = base::TimeTicks();
invalidations_out_of_sync_ = !invalidations_enabled_;
for (TypeTrackerMap::iterator it = type_trackers_.begin();
it != type_trackers_.end(); ++it) {
it->second.RecordSuccessfulSyncCycle();
}
}
void NudgeTracker::RecordLocalChange(ModelTypeSet types) {
for (ModelTypeSet::Iterator type_it = types.First(); type_it.Good();
type_it.Inc()) {
TypeTrackerMap::iterator tracker_it = type_trackers_.find(type_it.Get());
DCHECK(tracker_it != type_trackers_.end());
tracker_it->second.RecordLocalChange();
}
}
void NudgeTracker::RecordLocalRefreshRequest(ModelTypeSet types) {
for (ModelTypeSet::Iterator it = types.First(); it.Good(); it.Inc()) {
TypeTrackerMap::iterator tracker_it = type_trackers_.find(it.Get());
DCHECK(tracker_it != type_trackers_.end());
tracker_it->second.RecordLocalRefreshRequest();
}
}
void NudgeTracker::RecordRemoteInvalidation(
const ObjectIdInvalidationMap& invalidation_map) {
ObjectIdSet id_set = invalidation_map.GetObjectIds();
for (ObjectIdSet::iterator it = id_set.begin(); it != id_set.end(); ++it) {
ModelType type;
if (!ObjectIdToRealModelType(*it, &type)) {
NOTREACHED()
<< "Object ID " << ObjectIdToString(*it)
<< " does not map to valid model type";
continue;
}
TypeTrackerMap::iterator tracker_it = type_trackers_.find(type);
DCHECK(tracker_it != type_trackers_.end());
tracker_it->second.RecordRemoteInvalidations(
invalidation_map.ForObject(*it));
}
}
void NudgeTracker::OnInvalidationsEnabled() {
invalidations_enabled_ = true;
}
void NudgeTracker::OnInvalidationsDisabled() {
invalidations_enabled_ = false;
invalidations_out_of_sync_ = true;
}
void NudgeTracker::SetTypesThrottledUntil(
ModelTypeSet types,
base::TimeDelta length,
base::TimeTicks now) {
for (ModelTypeSet::Iterator it = types.First(); it.Good(); it.Inc()) {
TypeTrackerMap::iterator tracker_it = type_trackers_.find(it.Get());
tracker_it->second.ThrottleType(length, now);
}
}
void NudgeTracker::UpdateTypeThrottlingState(base::TimeTicks now) {
for (TypeTrackerMap::iterator it = type_trackers_.begin();
it != type_trackers_.end(); ++it) {
it->second.UpdateThrottleState(now);
}
}
bool NudgeTracker::IsAnyTypeThrottled() const {
for (TypeTrackerMap::const_iterator it = type_trackers_.begin();
it != type_trackers_.end(); ++it) {
if (it->second.IsThrottled()) {
return true;
}
}
return false;
}
bool NudgeTracker::IsTypeThrottled(ModelType type) const {
DCHECK(type_trackers_.find(type) != type_trackers_.end());
return type_trackers_.find(type)->second.IsThrottled();
}
base::TimeDelta NudgeTracker::GetTimeUntilNextUnthrottle(
base::TimeTicks now) const {
DCHECK(IsAnyTypeThrottled()) << "This function requires a pending unthrottle";
base::TimeDelta time_until_next_unthrottle = base::TimeDelta::Max();
for (TypeTrackerMap::const_iterator it = type_trackers_.begin();
it != type_trackers_.end(); ++it) {
if (it->second.IsThrottled()) {
time_until_next_unthrottle =
std::min(time_until_next_unthrottle,
it->second.GetTimeUntilUnthrottle(now));
}
}
DCHECK(!time_until_next_unthrottle.is_max());
return time_until_next_unthrottle;
}
ModelTypeSet NudgeTracker::GetThrottledTypes() const {
ModelTypeSet result;
for (TypeTrackerMap::const_iterator it = type_trackers_.begin();
it != type_trackers_.end(); ++it) {
if (it->second.IsThrottled()) {
result.Put(it->first);
}
}
return result;
}
ModelTypeSet NudgeTracker::GetNudgedTypes() const {
ModelTypeSet result;
for (TypeTrackerMap::const_iterator it = type_trackers_.begin();
it != type_trackers_.end(); ++it) {
if (it->second.HasLocalChangePending()) {
result.Put(it->first);
}
}
return result;
}
ModelTypeSet NudgeTracker::GetNotifiedTypes() const {
ModelTypeSet result;
for (TypeTrackerMap::const_iterator it = type_trackers_.begin();
it != type_trackers_.end(); ++it) {
if (it->second.HasPendingInvalidation()) {
result.Put(it->first);
}
}
return result;
}
ModelTypeSet NudgeTracker::GetRefreshRequestedTypes() const {
ModelTypeSet result;
for (TypeTrackerMap::const_iterator it = type_trackers_.begin();
it != type_trackers_.end(); ++it) {
if (it->second.HasRefreshRequestPending()) {
result.Put(it->first);
}
}
return result;
}
void NudgeTracker::SetLegacyNotificationHint(
ModelType type,
sync_pb::DataTypeProgressMarker* progress) const {
DCHECK(type_trackers_.find(type) != type_trackers_.end());
type_trackers_.find(type)->second.SetLegacyNotificationHint(progress);
}
sync_pb::GetUpdatesCallerInfo::GetUpdatesSource NudgeTracker::GetLegacySource()
const {
bool has_invalidation_pending = false;
bool has_refresh_request_pending = false;
bool has_commit_pending = false;
bool has_retry = IsRetryRequired();
for (TypeTrackerMap::const_iterator it = type_trackers_.begin();
it != type_trackers_.end(); ++it) {
const DataTypeTracker& tracker = it->second;
if (!tracker.IsThrottled() && tracker.HasPendingInvalidation()) {
has_invalidation_pending = true;
}
if (!tracker.IsThrottled() && tracker.HasRefreshRequestPending()) {
has_refresh_request_pending = true;
}
if (!tracker.IsThrottled() && tracker.HasLocalChangePending()) {
has_commit_pending = true;
}
}
if (has_invalidation_pending) {
return sync_pb::GetUpdatesCallerInfo::NOTIFICATION;
} else if (has_refresh_request_pending) {
return sync_pb::GetUpdatesCallerInfo::DATATYPE_REFRESH;
} else if (has_commit_pending) {
return sync_pb::GetUpdatesCallerInfo::LOCAL;
} else if (has_retry) {
return sync_pb::GetUpdatesCallerInfo::RETRY;
} else {
return sync_pb::GetUpdatesCallerInfo::UNKNOWN;
}
}
void NudgeTracker::FillProtoMessage(
ModelType type,
sync_pb::GetUpdateTriggers* msg) const {
DCHECK(type_trackers_.find(type) != type_trackers_.end());
msg->set_invalidations_out_of_sync(invalidations_out_of_sync_);
type_trackers_.find(type)->second.FillGetUpdatesTriggersMessage(msg);
}
void NudgeTracker::SetSyncCycleStartTime(base::TimeTicks now) {
sync_cycle_start_time_ = now;
if (!current_retry_time_.is_null()) {
return;
}
if (!next_retry_time_.is_null() &&
next_retry_time_ < sync_cycle_start_time_) {
current_retry_time_ = next_retry_time_;
next_retry_time_ = base::TimeTicks();
}
}
void NudgeTracker::SetHintBufferSize(size_t size) {
for (TypeTrackerMap::iterator it = type_trackers_.begin();
it != type_trackers_.end(); ++it) {
it->second.UpdatePayloadBufferSize(size);
}
}
void NudgeTracker::SetNextRetryTime(base::TimeTicks retry_time) {
next_retry_time_ = retry_time;
}
}
}