| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/invalidation/impl/registration_manager.h" | 5 #include "components/invalidation/impl/registration_manager.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <cstddef> | 10 #include <cstddef> |
| 11 #include <iterator> | 11 #include <iterator> |
| 12 #include <string> | 12 #include <string> |
| 13 #include <utility> | 13 #include <utility> |
| 14 | 14 |
| 15 #include "base/memory/ptr_util.h" |
| 15 #include "base/rand_util.h" | 16 #include "base/rand_util.h" |
| 16 #include "base/stl_util.h" | 17 #include "base/stl_util.h" |
| 17 #include "components/invalidation/public/invalidation_util.h" | 18 #include "components/invalidation/public/invalidation_util.h" |
| 18 #include "google/cacheinvalidation/include/invalidation-client.h" | 19 #include "google/cacheinvalidation/include/invalidation-client.h" |
| 19 #include "google/cacheinvalidation/include/types.h" | 20 #include "google/cacheinvalidation/include/types.h" |
| 20 | 21 |
| 21 namespace syncer { | 22 namespace syncer { |
| 22 | 23 |
| 23 RegistrationManager::PendingRegistrationInfo::PendingRegistrationInfo() {} | 24 RegistrationManager::PendingRegistrationInfo::PendingRegistrationInfo() {} |
| 24 | 25 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 const int RegistrationManager::kMaxRegistrationDelaySeconds = 60 * 60; | 59 const int RegistrationManager::kMaxRegistrationDelaySeconds = 60 * 60; |
| 59 | 60 |
| 60 RegistrationManager::RegistrationManager( | 61 RegistrationManager::RegistrationManager( |
| 61 invalidation::InvalidationClient* invalidation_client) | 62 invalidation::InvalidationClient* invalidation_client) |
| 62 : invalidation_client_(invalidation_client) { | 63 : invalidation_client_(invalidation_client) { |
| 63 DCHECK(invalidation_client_); | 64 DCHECK(invalidation_client_); |
| 64 } | 65 } |
| 65 | 66 |
| 66 RegistrationManager::~RegistrationManager() { | 67 RegistrationManager::~RegistrationManager() { |
| 67 DCHECK(CalledOnValidThread()); | 68 DCHECK(CalledOnValidThread()); |
| 68 base::STLDeleteValues(®istration_statuses_); | |
| 69 } | 69 } |
| 70 | 70 |
| 71 ObjectIdSet RegistrationManager::UpdateRegisteredIds(const ObjectIdSet& ids) { | 71 ObjectIdSet RegistrationManager::UpdateRegisteredIds(const ObjectIdSet& ids) { |
| 72 DCHECK(CalledOnValidThread()); | 72 DCHECK(CalledOnValidThread()); |
| 73 | 73 |
| 74 const ObjectIdSet& old_ids = GetRegisteredIds(); | 74 const ObjectIdSet& old_ids = GetRegisteredIds(); |
| 75 const ObjectIdSet& to_register = ids; | 75 const ObjectIdSet& to_register = ids; |
| 76 ObjectIdSet to_unregister; | 76 ObjectIdSet to_unregister; |
| 77 std::set_difference(old_ids.begin(), old_ids.end(), | 77 std::set_difference(old_ids.begin(), old_ids.end(), |
| 78 ids.begin(), ids.end(), | 78 ids.begin(), ids.end(), |
| 79 std::inserter(to_unregister, to_unregister.begin()), | 79 std::inserter(to_unregister, to_unregister.begin()), |
| 80 ObjectIdLessThan()); | 80 ObjectIdLessThan()); |
| 81 | 81 |
| 82 for (ObjectIdSet::const_iterator it = to_unregister.begin(); | 82 for (ObjectIdSet::const_iterator it = to_unregister.begin(); |
| 83 it != to_unregister.end(); ++it) { | 83 it != to_unregister.end(); ++it) { |
| 84 UnregisterId(*it); | 84 UnregisterId(*it); |
| 85 } | 85 } |
| 86 | 86 |
| 87 for (ObjectIdSet::const_iterator it = to_register.begin(); | 87 for (ObjectIdSet::const_iterator it = to_register.begin(); |
| 88 it != to_register.end(); ++it) { | 88 it != to_register.end(); ++it) { |
| 89 if (!base::ContainsKey(registration_statuses_, *it)) { | 89 if (!base::ContainsKey(registration_statuses_, *it)) { |
| 90 registration_statuses_.insert( | 90 registration_statuses_[*it] = |
| 91 std::make_pair(*it, new RegistrationStatus(*it, this))); | 91 base::MakeUnique<RegistrationStatus>(*it, this); |
| 92 } | 92 } |
| 93 if (!IsIdRegistered(*it)) { | 93 if (!IsIdRegistered(*it)) { |
| 94 TryRegisterId(*it, false /* is-retry */); | 94 TryRegisterId(*it, false /* is-retry */); |
| 95 } | 95 } |
| 96 } | 96 } |
| 97 | 97 |
| 98 return to_unregister; | 98 return to_unregister; |
| 99 } | 99 } |
| 100 | 100 |
| 101 void RegistrationManager::MarkRegistrationLost( | 101 void RegistrationManager::MarkRegistrationLost( |
| 102 const invalidation::ObjectId& id) { | 102 const invalidation::ObjectId& id) { |
| 103 DCHECK(CalledOnValidThread()); | 103 DCHECK(CalledOnValidThread()); |
| 104 RegistrationStatusMap::const_iterator it = registration_statuses_.find(id); | 104 auto it = registration_statuses_.find(id); |
| 105 if (it == registration_statuses_.end()) { | 105 if (it == registration_statuses_.end()) { |
| 106 DVLOG(1) << "Attempt to mark non-existent registration for " | 106 DVLOG(1) << "Attempt to mark non-existent registration for " |
| 107 << ObjectIdToString(id) << " as lost"; | 107 << ObjectIdToString(id) << " as lost"; |
| 108 return; | 108 return; |
| 109 } | 109 } |
| 110 if (!it->second->enabled) { | 110 if (!it->second->enabled) { |
| 111 return; | 111 return; |
| 112 } | 112 } |
| 113 it->second->state = invalidation::InvalidationListener::UNREGISTERED; | 113 it->second->state = invalidation::InvalidationListener::UNREGISTERED; |
| 114 bool is_retry = !it->second->last_registration_request.is_null(); | 114 bool is_retry = !it->second->last_registration_request.is_null(); |
| 115 TryRegisterId(id, is_retry); | 115 TryRegisterId(id, is_retry); |
| 116 } | 116 } |
| 117 | 117 |
| 118 void RegistrationManager::MarkAllRegistrationsLost() { | 118 void RegistrationManager::MarkAllRegistrationsLost() { |
| 119 DCHECK(CalledOnValidThread()); | 119 DCHECK(CalledOnValidThread()); |
| 120 for (RegistrationStatusMap::const_iterator it = | 120 for (auto it = registration_statuses_.begin(); |
| 121 registration_statuses_.begin(); | |
| 122 it != registration_statuses_.end(); ++it) { | 121 it != registration_statuses_.end(); ++it) { |
| 123 if (IsIdRegistered(it->first)) { | 122 if (IsIdRegistered(it->first)) { |
| 124 MarkRegistrationLost(it->first); | 123 MarkRegistrationLost(it->first); |
| 125 } | 124 } |
| 126 } | 125 } |
| 127 } | 126 } |
| 128 | 127 |
| 129 void RegistrationManager::DisableId(const invalidation::ObjectId& id) { | 128 void RegistrationManager::DisableId(const invalidation::ObjectId& id) { |
| 130 DCHECK(CalledOnValidThread()); | 129 DCHECK(CalledOnValidThread()); |
| 131 RegistrationStatusMap::const_iterator it = registration_statuses_.find(id); | 130 auto it = registration_statuses_.find(id); |
| 132 if (it == registration_statuses_.end()) { | 131 if (it == registration_statuses_.end()) { |
| 133 DVLOG(1) << "Attempt to disable non-existent registration for " | 132 DVLOG(1) << "Attempt to disable non-existent registration for " |
| 134 << ObjectIdToString(id); | 133 << ObjectIdToString(id); |
| 135 return; | 134 return; |
| 136 } | 135 } |
| 137 it->second->Disable(); | 136 it->second->Disable(); |
| 138 } | 137 } |
| 139 | 138 |
| 140 // static | 139 // static |
| 141 double RegistrationManager::CalculateBackoff( | 140 double RegistrationManager::CalculateBackoff( |
| (...skipping 15 matching lines...) Expand all Loading... |
| 157 } | 156 } |
| 158 | 157 |
| 159 ObjectIdSet RegistrationManager::GetRegisteredIdsForTest() const { | 158 ObjectIdSet RegistrationManager::GetRegisteredIdsForTest() const { |
| 160 return GetRegisteredIds(); | 159 return GetRegisteredIds(); |
| 161 } | 160 } |
| 162 | 161 |
| 163 RegistrationManager::PendingRegistrationMap | 162 RegistrationManager::PendingRegistrationMap |
| 164 RegistrationManager::GetPendingRegistrationsForTest() const { | 163 RegistrationManager::GetPendingRegistrationsForTest() const { |
| 165 DCHECK(CalledOnValidThread()); | 164 DCHECK(CalledOnValidThread()); |
| 166 PendingRegistrationMap pending_registrations; | 165 PendingRegistrationMap pending_registrations; |
| 167 for (RegistrationStatusMap::const_iterator it = | 166 for (const auto& status_pair : registration_statuses_) { |
| 168 registration_statuses_.begin(); | 167 const invalidation::ObjectId& id = status_pair.first; |
| 169 it != registration_statuses_.end(); ++it) { | 168 RegistrationStatus* status = status_pair.second.get(); |
| 170 const invalidation::ObjectId& id = it->first; | |
| 171 RegistrationStatus* status = it->second; | |
| 172 if (status->registration_timer.IsRunning()) { | 169 if (status->registration_timer.IsRunning()) { |
| 173 pending_registrations[id].last_registration_request = | 170 pending_registrations[id].last_registration_request = |
| 174 status->last_registration_request; | 171 status->last_registration_request; |
| 175 pending_registrations[id].registration_attempt = | 172 pending_registrations[id].registration_attempt = |
| 176 status->last_registration_attempt; | 173 status->last_registration_attempt; |
| 177 pending_registrations[id].delay = status->delay; | 174 pending_registrations[id].delay = status->delay; |
| 178 pending_registrations[id].actual_delay = | 175 pending_registrations[id].actual_delay = |
| 179 status->registration_timer.GetCurrentDelay(); | 176 status->registration_timer.GetCurrentDelay(); |
| 180 } | 177 } |
| 181 } | 178 } |
| 182 return pending_registrations; | 179 return pending_registrations; |
| 183 } | 180 } |
| 184 | 181 |
| 185 void RegistrationManager::FirePendingRegistrationsForTest() { | 182 void RegistrationManager::FirePendingRegistrationsForTest() { |
| 186 DCHECK(CalledOnValidThread()); | 183 DCHECK(CalledOnValidThread()); |
| 187 for (RegistrationStatusMap::const_iterator it = | 184 for (const auto& status_pair : registration_statuses_) { |
| 188 registration_statuses_.begin(); | 185 if (status_pair.second->registration_timer.IsRunning()) { |
| 189 it != registration_statuses_.end(); ++it) { | 186 status_pair.second->DoRegister(); |
| 190 if (it->second->registration_timer.IsRunning()) { | |
| 191 it->second->DoRegister(); | |
| 192 } | 187 } |
| 193 } | 188 } |
| 194 } | 189 } |
| 195 | 190 |
| 196 double RegistrationManager::GetJitter() { | 191 double RegistrationManager::GetJitter() { |
| 197 // |jitter| lies in [-1.0, 1.0), which is low-biased, but only | 192 // |jitter| lies in [-1.0, 1.0), which is low-biased, but only |
| 198 // barely. | 193 // barely. |
| 199 // | 194 // |
| 200 // TODO(akalin): Fix the bias. | 195 // TODO(akalin): Fix the bias. |
| 201 return 2.0 * base::RandDouble() - 1.0; | 196 return 2.0 * base::RandDouble() - 1.0; |
| 202 } | 197 } |
| 203 | 198 |
| 204 void RegistrationManager::TryRegisterId(const invalidation::ObjectId& id, | 199 void RegistrationManager::TryRegisterId(const invalidation::ObjectId& id, |
| 205 bool is_retry) { | 200 bool is_retry) { |
| 206 DCHECK(CalledOnValidThread()); | 201 DCHECK(CalledOnValidThread()); |
| 207 RegistrationStatusMap::const_iterator it = registration_statuses_.find(id); | 202 auto it = registration_statuses_.find(id); |
| 208 if (it == registration_statuses_.end()) { | 203 if (it == registration_statuses_.end()) { |
| 209 NOTREACHED() << "TryRegisterId called on " << ObjectIdToString(id) | 204 NOTREACHED() << "TryRegisterId called on " << ObjectIdToString(id) |
| 210 << " which is not in the registration map"; | 205 << " which is not in the registration map"; |
| 211 return; | 206 return; |
| 212 } | 207 } |
| 213 RegistrationStatus* status = it->second; | 208 RegistrationStatus* status = it->second.get(); |
| 214 if (!status->enabled) { | 209 if (!status->enabled) { |
| 215 // Disabled, so do nothing. | 210 // Disabled, so do nothing. |
| 216 return; | 211 return; |
| 217 } | 212 } |
| 218 status->last_registration_attempt = base::Time::Now(); | 213 status->last_registration_attempt = base::Time::Now(); |
| 219 if (is_retry) { | 214 if (is_retry) { |
| 220 // If we're a retry, we must have tried at least once before. | 215 // If we're a retry, we must have tried at least once before. |
| 221 DCHECK(!status->last_registration_request.is_null()); | 216 DCHECK(!status->last_registration_request.is_null()); |
| 222 // delay = max(0, (now - last request) + next_delay) | 217 // delay = max(0, (now - last request) + next_delay) |
| 223 status->delay = | 218 status->delay = |
| (...skipping 27 matching lines...) Expand all Loading... |
| 251 << ObjectIdToString(id) << " immediately"; | 246 << ObjectIdToString(id) << " immediately"; |
| 252 status->delay = base::TimeDelta(); | 247 status->delay = base::TimeDelta(); |
| 253 status->next_delay = base::TimeDelta(); | 248 status->next_delay = base::TimeDelta(); |
| 254 status->DoRegister(); | 249 status->DoRegister(); |
| 255 } | 250 } |
| 256 } | 251 } |
| 257 | 252 |
| 258 void RegistrationManager::DoRegisterId(const invalidation::ObjectId& id) { | 253 void RegistrationManager::DoRegisterId(const invalidation::ObjectId& id) { |
| 259 DCHECK(CalledOnValidThread()); | 254 DCHECK(CalledOnValidThread()); |
| 260 invalidation_client_->Register(id); | 255 invalidation_client_->Register(id); |
| 261 RegistrationStatusMap::const_iterator it = registration_statuses_.find(id); | 256 auto it = registration_statuses_.find(id); |
| 262 if (it == registration_statuses_.end()) { | 257 if (it == registration_statuses_.end()) { |
| 263 NOTREACHED() << "DoRegisterId called on " << ObjectIdToString(id) | 258 NOTREACHED() << "DoRegisterId called on " << ObjectIdToString(id) |
| 264 << " which is not in the registration map"; | 259 << " which is not in the registration map"; |
| 265 return; | 260 return; |
| 266 } | 261 } |
| 267 it->second->state = invalidation::InvalidationListener::REGISTERED; | 262 it->second->state = invalidation::InvalidationListener::REGISTERED; |
| 268 it->second->last_registration_request = base::Time::Now(); | 263 it->second->last_registration_request = base::Time::Now(); |
| 269 } | 264 } |
| 270 | 265 |
| 271 void RegistrationManager::UnregisterId(const invalidation::ObjectId& id) { | 266 void RegistrationManager::UnregisterId(const invalidation::ObjectId& id) { |
| 272 DCHECK(CalledOnValidThread()); | 267 DCHECK(CalledOnValidThread()); |
| 273 invalidation_client_->Unregister(id); | 268 invalidation_client_->Unregister(id); |
| 274 RegistrationStatusMap::iterator it = registration_statuses_.find(id); | 269 auto it = registration_statuses_.find(id); |
| 275 if (it == registration_statuses_.end()) { | 270 if (it == registration_statuses_.end()) { |
| 276 NOTREACHED() << "UnregisterId called on " << ObjectIdToString(id) | 271 NOTREACHED() << "UnregisterId called on " << ObjectIdToString(id) |
| 277 << " which is not in the registration map"; | 272 << " which is not in the registration map"; |
| 278 return; | 273 return; |
| 279 } | 274 } |
| 280 delete it->second; | |
| 281 registration_statuses_.erase(it); | 275 registration_statuses_.erase(it); |
| 282 } | 276 } |
| 283 | 277 |
| 284 | 278 |
| 285 ObjectIdSet RegistrationManager::GetRegisteredIds() const { | 279 ObjectIdSet RegistrationManager::GetRegisteredIds() const { |
| 286 DCHECK(CalledOnValidThread()); | 280 DCHECK(CalledOnValidThread()); |
| 287 ObjectIdSet ids; | 281 ObjectIdSet ids; |
| 288 for (RegistrationStatusMap::const_iterator it = | 282 for (const auto& status_pair : registration_statuses_) { |
| 289 registration_statuses_.begin(); | 283 if (IsIdRegistered(status_pair.first)) { |
| 290 it != registration_statuses_.end(); ++it) { | 284 ids.insert(status_pair.first); |
| 291 if (IsIdRegistered(it->first)) { | |
| 292 ids.insert(it->first); | |
| 293 } | 285 } |
| 294 } | 286 } |
| 295 return ids; | 287 return ids; |
| 296 } | 288 } |
| 297 | 289 |
| 298 bool RegistrationManager::IsIdRegistered( | 290 bool RegistrationManager::IsIdRegistered( |
| 299 const invalidation::ObjectId& id) const { | 291 const invalidation::ObjectId& id) const { |
| 300 DCHECK(CalledOnValidThread()); | 292 DCHECK(CalledOnValidThread()); |
| 301 RegistrationStatusMap::const_iterator it = | 293 auto it = registration_statuses_.find(id); |
| 302 registration_statuses_.find(id); | |
| 303 return it != registration_statuses_.end() && | 294 return it != registration_statuses_.end() && |
| 304 it->second->state == invalidation::InvalidationListener::REGISTERED; | 295 it->second->state == invalidation::InvalidationListener::REGISTERED; |
| 305 } | 296 } |
| 306 | 297 |
| 307 } // namespace syncer | 298 } // namespace syncer |
| OLD | NEW |