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

Side by Side Diff: chrome/browser/policy/cloud/cloud_policy_invalidator.cc

Issue 23754021: Invalidation trickles mega-patch (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "chrome/browser/policy/cloud/cloud_policy_invalidator.h" 5 #include "chrome/browser/policy/cloud/cloud_policy_invalidator.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/hash.h" 9 #include "base/hash.h"
10 #include "base/location.h" 10 #include "base/location.h"
(...skipping 24 matching lines...) Expand all
35 : state_(UNINITIALIZED), 35 : state_(UNINITIALIZED),
36 core_(core), 36 core_(core),
37 task_runner_(task_runner), 37 task_runner_(task_runner),
38 invalidation_service_(NULL), 38 invalidation_service_(NULL),
39 invalidations_enabled_(false), 39 invalidations_enabled_(false),
40 invalidation_service_enabled_(false), 40 invalidation_service_enabled_(false),
41 registered_timestamp_(0), 41 registered_timestamp_(0),
42 invalid_(false), 42 invalid_(false),
43 invalidation_version_(0), 43 invalidation_version_(0),
44 unknown_version_invalidation_count_(0), 44 unknown_version_invalidation_count_(0),
45 ack_handle_(syncer::AckHandle::InvalidAckHandle()),
46 weak_factory_(this), 45 weak_factory_(this),
47 max_fetch_delay_(kMaxFetchDelayDefault), 46 max_fetch_delay_(kMaxFetchDelayDefault),
48 policy_hash_value_(0) { 47 policy_hash_value_(0) {
49 DCHECK(core); 48 DCHECK(core);
50 DCHECK(task_runner.get()); 49 DCHECK(task_runner.get());
51 } 50 }
52 51
53 CloudPolicyInvalidator::~CloudPolicyInvalidator() { 52 CloudPolicyInvalidator::~CloudPolicyInvalidator() {
54 DCHECK(state_ == SHUT_DOWN); 53 DCHECK(state_ == SHUT_DOWN);
55 } 54 }
(...skipping 29 matching lines...) Expand all
85 DCHECK(state_ == STARTED); 84 DCHECK(state_ == STARTED);
86 DCHECK(thread_checker_.CalledOnValidThread()); 85 DCHECK(thread_checker_.CalledOnValidThread());
87 invalidation_service_enabled_ = state == syncer::INVALIDATIONS_ENABLED; 86 invalidation_service_enabled_ = state == syncer::INVALIDATIONS_ENABLED;
88 UpdateInvalidationsEnabled(); 87 UpdateInvalidationsEnabled();
89 } 88 }
90 89
91 void CloudPolicyInvalidator::OnIncomingInvalidation( 90 void CloudPolicyInvalidator::OnIncomingInvalidation(
92 const syncer::ObjectIdInvalidationMap& invalidation_map) { 91 const syncer::ObjectIdInvalidationMap& invalidation_map) {
93 DCHECK(state_ == STARTED); 92 DCHECK(state_ == STARTED);
94 DCHECK(thread_checker_.CalledOnValidThread()); 93 DCHECK(thread_checker_.CalledOnValidThread());
95 const syncer::ObjectIdInvalidationMap::const_iterator invalidation = 94
96 invalidation_map.find(object_id_); 95 const syncer::OrderedInvalidationList& list =
97 if (invalidation == invalidation_map.end()) { 96 invalidation_map.ForObject(object_id_);
97 if (list.IsEmpty()) {
98 NOTREACHED(); 98 NOTREACHED();
99 return; 99 return;
100 } 100 }
101 HandleInvalidation(invalidation->second); 101
102 // Acknowledge all except the invalidation with the highest version.
103 syncer::OrderedInvalidationList::const_reverse_iterator it = list.rbegin();
104 ++it;
105 for ( ; it != list.rend(); ++it) {
106 it->Acknowledge();
107 }
108
109 HandleInvalidation(list.back());
102 } 110 }
103 111
104 void CloudPolicyInvalidator::OnCoreConnected(CloudPolicyCore* core) {} 112 void CloudPolicyInvalidator::OnCoreConnected(CloudPolicyCore* core) {}
105 113
106 void CloudPolicyInvalidator::OnRefreshSchedulerStarted(CloudPolicyCore* core) { 114 void CloudPolicyInvalidator::OnRefreshSchedulerStarted(CloudPolicyCore* core) {
107 DCHECK(state_ == STOPPED); 115 DCHECK(state_ == STOPPED);
108 DCHECK(thread_checker_.CalledOnValidThread()); 116 DCHECK(thread_checker_.CalledOnValidThread());
109 state_ = STARTED; 117 state_ = STARTED;
110 OnStoreLoaded(core_->store()); 118 OnStoreLoaded(core_->store());
111 core_->store()->AddObserver(this); 119 core_->store()->AddObserver(this);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 } 155 }
148 156
149 UpdateRegistration(store->policy()); 157 UpdateRegistration(store->policy());
150 UpdateMaxFetchDelay(store->policy_map()); 158 UpdateMaxFetchDelay(store->policy_map());
151 } 159 }
152 160
153 void CloudPolicyInvalidator::OnStoreError(CloudPolicyStore* store) {} 161 void CloudPolicyInvalidator::OnStoreError(CloudPolicyStore* store) {}
154 162
155 void CloudPolicyInvalidator::HandleInvalidation( 163 void CloudPolicyInvalidator::HandleInvalidation(
156 const syncer::Invalidation& invalidation) { 164 const syncer::Invalidation& invalidation) {
157 // The invalidation service may send an invalidation more than once if there 165 // Ignore old invalidations.
158 // is a delay in acknowledging it. Duplicate invalidations are ignored. 166 if (invalid_ &&
159 if (invalid_ && ack_handle_.Equals(invalidation.ack_handle)) 167 !invalidation.IsUnknownVersion() &&
168 invalidation.GetVersion() <= invalidation_version_) {
160 return; 169 return;
170 }
161 171
162 // If there is still a pending invalidation, acknowledge it, since we only 172 // If there is still a pending invalidation, acknowledge it, since we only
163 // care about the latest invalidation. 173 // care about the latest invalidation.
164 if (invalid_) 174 if (invalid_)
165 AcknowledgeInvalidation(); 175 AcknowledgeInvalidation();
166 176
167 // Update invalidation state. 177 // Update invalidation state.
168 invalid_ = true; 178 invalid_ = true;
169 ack_handle_ = invalidation.ack_handle; 179 invalidation_ = invalidation;
170 invalidation_version_ = invalidation.version; 180 if (invalidation.IsUnknownVersion()) {
171 181 // When an invalidation with unknown version is received, use negative
172 // When an invalidation with unknown version is received, use negative 182 // numbers based on the number of such invalidations received. This ensures
173 // numbers based on the number of such invalidations received. This 183 // that the version numbers do not collide with "real" versions (which are
174 // ensures that the version numbers do not collide with "real" versions 184 // positive) or previous invalidations with unknown version.
175 // (which are positive) or previous invalidations with unknown version.
176 if (invalidation_version_ == syncer::Invalidation::kUnknownVersion)
177 invalidation_version_ = -(++unknown_version_invalidation_count_); 185 invalidation_version_ = -(++unknown_version_invalidation_count_);
186 } else {
187 invalidation_version_ = invalidation.GetVersion();
188 }
178 189
179 // In order to prevent the cloud policy server from becoming overwhelmed when 190 // In order to prevent the cloud policy server from becoming overwhelmed when
180 // a policy with many users is modified, delay for a random period of time 191 // a policy with many users is modified, delay for a random period of time
181 // before fetching the policy. Delay for at least 20ms so that if multiple 192 // before fetching the policy. Delay for at least 20ms so that if multiple
182 // invalidations are received in quick succession, only one fetch will be 193 // invalidations are received in quick succession, only one fetch will be
183 // performed. 194 // performed.
184 base::TimeDelta delay = base::TimeDelta::FromMilliseconds( 195 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(
185 base::RandInt(20, max_fetch_delay_)); 196 base::RandInt(20, max_fetch_delay_));
186 197
187 // If there is a payload, the policy can be refreshed at any time, so set 198 std::string payload;
188 // the version and payload on the client immediately. Otherwise, the refresh 199 if (!invalidation.IsUnknownVersion())
200 payload = invalidation.GetPayload();
201
202 // If there is a payload, the invalidate callback can run at any time, so set
203 // the version and payload on the client immediately. Otherwise, the callback
189 // must only run after at least kMissingPayloadDelay minutes. 204 // must only run after at least kMissingPayloadDelay minutes.
190 const std::string& payload = invalidation.payload; 205 if (!payload.empty())
191 if (!invalidation.payload.empty())
192 core_->client()->SetInvalidationInfo(invalidation_version_, payload); 206 core_->client()->SetInvalidationInfo(invalidation_version_, payload);
193 else 207 else
194 delay += base::TimeDelta::FromMinutes(kMissingPayloadDelay); 208 delay += base::TimeDelta::FromMinutes(kMissingPayloadDelay);
195 209
196 // Schedule the policy to be refreshed. 210 // Schedule the policy to be refreshed.
197 task_runner_->PostDelayedTask( 211 task_runner_->PostDelayedTask(
198 FROM_HERE, 212 FROM_HERE,
199 base::Bind( 213 base::Bind(
200 &CloudPolicyInvalidator::RefreshPolicy, 214 &CloudPolicyInvalidator::RefreshPolicy,
201 weak_factory_.GetWeakPtr(), 215 weak_factory_.GetWeakPtr(),
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 // the client yet, so set it now that the required time has elapsed. 324 // the client yet, so set it now that the required time has elapsed.
311 if (is_missing_payload) 325 if (is_missing_payload)
312 core_->client()->SetInvalidationInfo(invalidation_version_, std::string()); 326 core_->client()->SetInvalidationInfo(invalidation_version_, std::string());
313 core_->refresh_scheduler()->RefreshSoon(); 327 core_->refresh_scheduler()->RefreshSoon();
314 } 328 }
315 329
316 void CloudPolicyInvalidator::AcknowledgeInvalidation() { 330 void CloudPolicyInvalidator::AcknowledgeInvalidation() {
317 DCHECK(invalid_); 331 DCHECK(invalid_);
318 invalid_ = false; 332 invalid_ = false;
319 core_->client()->SetInvalidationInfo(0, std::string()); 333 core_->client()->SetInvalidationInfo(0, std::string());
320 invalidation_service_->AcknowledgeInvalidation(object_id_, ack_handle_); 334 invalidation_.Acknowledge();
321 // Cancel any scheduled policy refreshes. 335 invalidation_ = syncer::Invalidation();
336 // Cancel any scheduled invalidate callbacks.
322 weak_factory_.InvalidateWeakPtrs(); 337 weak_factory_.InvalidateWeakPtrs();
323 } 338 }
324 339
325 bool CloudPolicyInvalidator::IsPolicyChanged( 340 bool CloudPolicyInvalidator::IsPolicyChanged(
326 const enterprise_management::PolicyData* policy) { 341 const enterprise_management::PolicyData* policy) {
327 // Determine if the policy changed by comparing its hash value to the 342 // Determine if the policy changed by comparing its hash value to the
328 // previous policy's hash value. 343 // previous policy's hash value.
329 uint32 new_hash_value = 0; 344 uint32 new_hash_value = 0;
330 if (policy && policy->has_policy_value()) 345 if (policy && policy->has_policy_value())
331 new_hash_value = base::Hash(policy->policy_value()); 346 new_hash_value = base::Hash(policy->policy_value());
332 bool changed = new_hash_value != policy_hash_value_; 347 bool changed = new_hash_value != policy_hash_value_;
333 policy_hash_value_ = new_hash_value; 348 policy_hash_value_ = new_hash_value;
334 return changed; 349 return changed;
335 } 350 }
336 351
337 int CloudPolicyInvalidator::GetPolicyRefreshMetric(bool policy_changed) { 352 int CloudPolicyInvalidator::GetPolicyRefreshMetric(bool policy_changed) {
338 if (policy_changed) { 353 if (policy_changed) {
339 if (invalid_) 354 if (invalid_)
340 return METRIC_POLICY_REFRESH_INVALIDATED_CHANGED; 355 return METRIC_POLICY_REFRESH_INVALIDATED_CHANGED;
341 if (invalidations_enabled_) 356 if (invalidations_enabled_)
342 return METRIC_POLICY_REFRESH_CHANGED; 357 return METRIC_POLICY_REFRESH_CHANGED;
343 return METRIC_POLICY_REFRESH_CHANGED_NO_INVALIDATIONS; 358 return METRIC_POLICY_REFRESH_CHANGED_NO_INVALIDATIONS;
344 } 359 }
345 if (invalid_) 360 if (invalid_)
346 return METRIC_POLICY_REFRESH_INVALIDATED_UNCHANGED; 361 return METRIC_POLICY_REFRESH_INVALIDATED_UNCHANGED;
347 return METRIC_POLICY_REFRESH_UNCHANGED; 362 return METRIC_POLICY_REFRESH_UNCHANGED;
348 } 363 }
349 364
350 } // namespace policy 365 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698