1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "sync/sessions/nudge_tracker.h" 6b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 77d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/basictypes.h" 8b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "sync/internal_api/public/base/invalidation.h" 958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "sync/notifier/invalidation_util.h" 1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "sync/notifier/object_id_invalidation_map.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "sync/protocol/sync.pb.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace syncer { 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace sessions { 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 16b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)size_t NudgeTracker::kDefaultMaxPayloadsPerType = 10; 17b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 18b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)NudgeTracker::NudgeTracker() 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : invalidations_enabled_(false), 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) invalidations_out_of_sync_(true) { 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ModelTypeSet protocol_types = ProtocolTypes(); 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Default initialize all the type trackers. 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (ModelTypeSet::Iterator it = protocol_types.First(); it.Good(); 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) it.Inc()) { 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) invalidation::ObjectId id; 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!RealModelTypeToObjectId(it.Get(), &id)) { 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOTREACHED(); 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) type_trackers_.insert(std::make_pair(it.Get(), DataTypeTracker(id))); 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)NudgeTracker::~NudgeTracker() { } 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool NudgeTracker::IsSyncRequired() const { 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (IsRetryRequired()) 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (TypeTrackerMap::const_iterator it = type_trackers_.begin(); 41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) it != type_trackers_.end(); ++it) { 42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (it->second.IsSyncRequired()) { 43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return true; 44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 45b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return false; 48b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 49b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 50ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool NudgeTracker::IsGetUpdatesRequired() const { 511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (invalidations_out_of_sync_) 521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return true; 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (IsRetryRequired()) 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 57ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch for (TypeTrackerMap::const_iterator it = type_trackers_.begin(); 58ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch it != type_trackers_.end(); ++it) { 59ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (it->second.IsGetUpdatesRequired()) { 60ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return true; 61ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 62ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 63ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return false; 64ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 65ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool NudgeTracker::IsRetryRequired() const { 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (sync_cycle_start_time_.is_null()) 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (current_retry_time_.is_null()) 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return current_retry_time_ < sync_cycle_start_time_; 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 76b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void NudgeTracker::RecordSuccessfulSyncCycle() { 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If a retry was required, we've just serviced it. Unset the flag. 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (IsRetryRequired()) 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) current_retry_time_ = base::TimeTicks(); 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 81b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // A successful cycle while invalidations are enabled puts us back into sync. 82b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) invalidations_out_of_sync_ = !invalidations_enabled_; 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (TypeTrackerMap::iterator it = type_trackers_.begin(); 85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) it != type_trackers_.end(); ++it) { 86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) it->second.RecordSuccessfulSyncCycle(); 87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 88b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 89b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 90b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void NudgeTracker::RecordLocalChange(ModelTypeSet types) { 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (ModelTypeSet::Iterator type_it = types.First(); type_it.Good(); 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) type_it.Inc()) { 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TypeTrackerMap::iterator tracker_it = type_trackers_.find(type_it.Get()); 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(tracker_it != type_trackers_.end()); 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) tracker_it->second.RecordLocalChange(); 96b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 97b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 98b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 99b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void NudgeTracker::RecordLocalRefreshRequest(ModelTypeSet types) { 100b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) for (ModelTypeSet::Iterator it = types.First(); it.Good(); it.Inc()) { 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TypeTrackerMap::iterator tracker_it = type_trackers_.find(it.Get()); 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(tracker_it != type_trackers_.end()); 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) tracker_it->second.RecordLocalRefreshRequest(); 104b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 107b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void NudgeTracker::RecordRemoteInvalidation( 10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const ObjectIdInvalidationMap& invalidation_map) { 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Be very careful here. The invalidations acknowledgement system requires a 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // sort of manual memory management. We'll leak a small amount of memory if 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // we fail to acknowledge or drop any of these incoming invalidations. 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ObjectIdSet id_set = invalidation_map.GetObjectIds(); 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (ObjectIdSet::iterator it = id_set.begin(); it != id_set.end(); ++it) { 11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ModelType type; 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This should never happen. If it does, we'll start to leak memory. 1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!ObjectIdToRealModelType(*it, &type)) { 11958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) NOTREACHED() 1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) << "Object ID " << ObjectIdToString(*it) 12158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) << " does not map to valid model type"; 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) continue; 12358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Forward the invalidations to the proper recipient. 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TypeTrackerMap::iterator tracker_it = type_trackers_.find(type); 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(tracker_it != type_trackers_.end()); 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) tracker_it->second.RecordRemoteInvalidations( 1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) invalidation_map.ForObject(*it)); 130b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 133b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void NudgeTracker::OnInvalidationsEnabled() { 134b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) invalidations_enabled_ = true; 135b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 136b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 137b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void NudgeTracker::OnInvalidationsDisabled() { 138b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) invalidations_enabled_ = false; 139b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) invalidations_out_of_sync_ = true; 140b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 141b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 1427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void NudgeTracker::SetTypesThrottledUntil( 1437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ModelTypeSet types, 1447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::TimeDelta length, 1457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::TimeTicks now) { 1467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) for (ModelTypeSet::Iterator it = types.First(); it.Good(); it.Inc()) { 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TypeTrackerMap::iterator tracker_it = type_trackers_.find(it.Get()); 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) tracker_it->second.ThrottleType(length, now); 1497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 1507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void NudgeTracker::UpdateTypeThrottlingState(base::TimeTicks now) { 1537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) for (TypeTrackerMap::iterator it = type_trackers_.begin(); 1547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) it != type_trackers_.end(); ++it) { 1557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) it->second.UpdateThrottleState(now); 1567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 1577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool NudgeTracker::IsAnyTypeThrottled() const { 1607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) for (TypeTrackerMap::const_iterator it = type_trackers_.begin(); 1617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) it != type_trackers_.end(); ++it) { 1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (it->second.IsThrottled()) { 1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return true; 1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 1657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 1667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return false; 1677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool NudgeTracker::IsTypeThrottled(ModelType type) const { 1707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(type_trackers_.find(type) != type_trackers_.end()); 1717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return type_trackers_.find(type)->second.IsThrottled(); 1727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)base::TimeDelta NudgeTracker::GetTimeUntilNextUnthrottle( 1757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::TimeTicks now) const { 1767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(IsAnyTypeThrottled()) << "This function requires a pending unthrottle"; 1777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Return min of GetTimeUntilUnthrottle() values for all IsThrottled() types. 179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::TimeDelta time_until_next_unthrottle = base::TimeDelta::Max(); 1807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) for (TypeTrackerMap::const_iterator it = type_trackers_.begin(); 1817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) it != type_trackers_.end(); ++it) { 1827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (it->second.IsThrottled()) { 1837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) time_until_next_unthrottle = 1847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) std::min(time_until_next_unthrottle, 1857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) it->second.GetTimeUntilUnthrottle(now)); 1867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 1877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!time_until_next_unthrottle.is_max()); 1897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return time_until_next_unthrottle; 1917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)ModelTypeSet NudgeTracker::GetThrottledTypes() const { 1947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ModelTypeSet result; 1957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) for (TypeTrackerMap::const_iterator it = type_trackers_.begin(); 1967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) it != type_trackers_.end(); ++it) { 1977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (it->second.IsThrottled()) { 1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) result.Put(it->first); 1997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return result; 2027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 20423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)ModelTypeSet NudgeTracker::GetNudgedTypes() const { 20523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ModelTypeSet result; 20623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) for (TypeTrackerMap::const_iterator it = type_trackers_.begin(); 20723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) it != type_trackers_.end(); ++it) { 20823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (it->second.HasLocalChangePending()) { 20923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) result.Put(it->first); 21023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 21123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 21223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return result; 21323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 21423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 21523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)ModelTypeSet NudgeTracker::GetNotifiedTypes() const { 21623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ModelTypeSet result; 21723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) for (TypeTrackerMap::const_iterator it = type_trackers_.begin(); 21823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) it != type_trackers_.end(); ++it) { 21923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (it->second.HasPendingInvalidation()) { 22023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) result.Put(it->first); 22123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 22223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 22323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return result; 22423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 22523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 22623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)ModelTypeSet NudgeTracker::GetRefreshRequestedTypes() const { 22723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ModelTypeSet result; 22823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) for (TypeTrackerMap::const_iterator it = type_trackers_.begin(); 22923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) it != type_trackers_.end(); ++it) { 23023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (it->second.HasRefreshRequestPending()) { 23123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) result.Put(it->first); 23223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 23323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 23423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return result; 23523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 23623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 237eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid NudgeTracker::SetLegacyNotificationHint( 238eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ModelType type, 239eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch sync_pb::DataTypeProgressMarker* progress) const { 240eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(type_trackers_.find(type) != type_trackers_.end()); 241eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch type_trackers_.find(type)->second.SetLegacyNotificationHint(progress); 242eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 243eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)sync_pb::GetUpdatesCallerInfo::GetUpdatesSource NudgeTracker::GetLegacySource() 245b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const { 246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // There's an order to these sources: NOTIFICATION, DATATYPE_REFRESH, LOCAL, 247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // RETRY. The server makes optimization decisions based on this field, so 248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // it's important to get this right. Setting it wrong could lead to missed 249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // updates. 250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // 251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // This complexity is part of the reason why we're deprecating 'source' in 252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // favor of 'origin'. 253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool has_invalidation_pending = false; 254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool has_refresh_request_pending = false; 255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool has_commit_pending = false; 256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool has_retry = IsRetryRequired(); 257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (TypeTrackerMap::const_iterator it = type_trackers_.begin(); 259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) it != type_trackers_.end(); ++it) { 260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const DataTypeTracker& tracker = it->second; 261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!tracker.IsThrottled() && tracker.HasPendingInvalidation()) { 262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) has_invalidation_pending = true; 263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!tracker.IsThrottled() && tracker.HasRefreshRequestPending()) { 265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) has_refresh_request_pending = true; 266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!tracker.IsThrottled() && tracker.HasLocalChangePending()) { 268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) has_commit_pending = true; 269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (has_invalidation_pending) { 273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return sync_pb::GetUpdatesCallerInfo::NOTIFICATION; 274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else if (has_refresh_request_pending) { 275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return sync_pb::GetUpdatesCallerInfo::DATATYPE_REFRESH; 276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else if (has_commit_pending) { 277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return sync_pb::GetUpdatesCallerInfo::LOCAL; 278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else if (has_retry) { 279a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return sync_pb::GetUpdatesCallerInfo::RETRY; 280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return sync_pb::GetUpdatesCallerInfo::UNKNOWN; 282a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 283b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 285b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void NudgeTracker::FillProtoMessage( 286b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ModelType type, 287b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) sync_pb::GetUpdateTriggers* msg) const { 288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(type_trackers_.find(type) != type_trackers_.end()); 289b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Fill what we can from the global data. 291b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) msg->set_invalidations_out_of_sync(invalidations_out_of_sync_); 292b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 2937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Delegate the type-specific work to the DataTypeTracker class. 294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) type_trackers_.find(type)->second.FillGetUpdatesTriggersMessage(msg); 295b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 296b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NudgeTracker::SetSyncCycleStartTime(base::TimeTicks now) { 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sync_cycle_start_time_ = now; 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If current_retry_time_ is still set, that means we have an old retry time 3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // left over from a previous cycle. For example, maybe we tried to perform 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // this retry, hit a network connection error, and now we're in exponential 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // backoff. In that case, we want this sync cycle to include the GU retry 3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // flag so we leave this variable set regardless of whether or not there is an 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // overwrite pending. 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!current_retry_time_.is_null()) { 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If do not have a current_retry_time_, but we do have a next_retry_time_ and 3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // it is ready to go, then we set it as the current_retry_time_. It will stay 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // there until a GU retry has succeeded. 3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!next_retry_time_.is_null() && 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) next_retry_time_ < sync_cycle_start_time_) { 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) current_retry_time_ = next_retry_time_; 3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) next_retry_time_ = base::TimeTicks(); 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 320b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void NudgeTracker::SetHintBufferSize(size_t size) { 321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (TypeTrackerMap::iterator it = type_trackers_.begin(); 322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) it != type_trackers_.end(); ++it) { 323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) it->second.UpdatePayloadBufferSize(size); 324868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NudgeTracker::SetNextRetryTime(base::TimeTicks retry_time) { 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) next_retry_time_ = retry_time; 3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace sessions 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace syncer 333