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

Side by Side Diff: components/policy/core/common/cloud/device_management_service.cc

Issue 2275553002: Don't retry fetching policies if it's a blocking operation, (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add test Created 4 years, 4 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 "components/policy/core/common/cloud/device_management_service.h" 5 #include "components/policy/core/common/cloud/device_management_service.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 void HandleResponse(const net::URLRequestStatus& status, 169 void HandleResponse(const net::URLRequestStatus& status,
170 int response_code, 170 int response_code,
171 const std::string& data); 171 const std::string& data);
172 172
173 // Gets the URL to contact. 173 // Gets the URL to contact.
174 GURL GetURL(const std::string& server_url); 174 GURL GetURL(const std::string& server_url);
175 175
176 // Configures the fetcher, setting up payload and headers. 176 // Configures the fetcher, setting up payload and headers.
177 void ConfigureRequest(net::URLFetcher* fetcher); 177 void ConfigureRequest(net::URLFetcher* fetcher);
178 178
179 // Returns true if this job should be retried. |fetcher| has just completed, 179 enum RetryMethod {
180 // and can be inspected to determine if the request failed and should be 180 // No retry required for this request.
181 // retried. 181 NO_RETRY,
182 bool ShouldRetry(const net::URLFetcher* fetcher); 182 // Should retry immediately (no delay).
183 RETRY_IMMEDIATELY,
184 // Should retry after a delay.
185 RETRY_WITH_DELAY
186 };
187
188 // Returns if and how this job should be retried. |fetcher| has just
189 // completed, and can be inspected to determine if the request failed and
190 // should be retried.
191 RetryMethod ShouldRetry(const net::URLFetcher* fetcher);
192
193 // Returns the delay before the next retry with the specified RetryMethod.
194 int GetRetryDelay(RetryMethod method);
183 195
184 // Invoked right before retrying this job. 196 // Invoked right before retrying this job.
185 void PrepareRetry(); 197 void PrepareRetry();
186 198
187 // Number of times that this job has been retried due to connection errors.
188 int retries_count() { return retries_count_; }
189
190 // Get weak pointer 199 // Get weak pointer
191 base::WeakPtr<DeviceManagementRequestJobImpl> GetWeakPtr() { 200 base::WeakPtr<DeviceManagementRequestJobImpl> GetWeakPtr() {
192 return weak_ptr_factory_.GetWeakPtr(); 201 return weak_ptr_factory_.GetWeakPtr();
193 } 202 }
194 203
195 protected: 204 protected:
196 // DeviceManagementRequestJob: 205 // DeviceManagementRequestJob:
197 void Run() override; 206 void Run() override;
198 207
199 private: 208 private:
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 CHECK(request_.SerializeToString(&payload)); 351 CHECK(request_.SerializeToString(&payload));
343 fetcher->SetUploadData(kPostContentType, payload); 352 fetcher->SetUploadData(kPostContentType, payload);
344 std::string extra_headers; 353 std::string extra_headers;
345 if (!gaia_token_.empty()) 354 if (!gaia_token_.empty())
346 extra_headers += kServiceTokenAuthHeader + gaia_token_ + "\n"; 355 extra_headers += kServiceTokenAuthHeader + gaia_token_ + "\n";
347 if (!dm_token_.empty()) 356 if (!dm_token_.empty())
348 extra_headers += kDMTokenAuthHeader + dm_token_ + "\n"; 357 extra_headers += kDMTokenAuthHeader + dm_token_ + "\n";
349 fetcher->SetExtraRequestHeaders(extra_headers); 358 fetcher->SetExtraRequestHeaders(extra_headers);
350 } 359 }
351 360
352 bool DeviceManagementRequestJobImpl::ShouldRetry( 361 DeviceManagementRequestJobImpl::RetryMethod
353 const net::URLFetcher* fetcher) { 362 DeviceManagementRequestJobImpl::ShouldRetry(const net::URLFetcher* fetcher) {
354 if (FailedWithProxy(fetcher) && !bypass_proxy_) { 363 if (FailedWithProxy(fetcher) && !bypass_proxy_) {
355 // Retry the job if it failed due to a broken proxy, by bypassing the 364 // Retry the job immediately if it failed due to a broken proxy, by
356 // proxy on the next try. 365 // bypassing the proxy on the next try.
357 bypass_proxy_ = true; 366 bypass_proxy_ = true;
358 return true; 367 return RETRY_IMMEDIATELY;
359 } 368 }
360 369
361 // Early device policy fetches on ChromeOS and Auto-Enrollment checks are 370 // Early device policy fetches on ChromeOS and Auto-Enrollment checks are
362 // often interrupted during ChromeOS startup when network is not yet ready. 371 // often interrupted during ChromeOS startup when network is not yet ready.
363 // Allowing the fetcher to retry once after that is enough to recover; allow 372 // Allowing the fetcher to retry once after that is enough to recover; allow
364 // it to retry up to 3 times just in case. 373 // it to retry up to 3 times just in case.
365 if (IsConnectionError(fetcher->GetStatus()) && retries_count_ < kMaxRetries) { 374 if (IsConnectionError(fetcher->GetStatus()) && retries_count_ < kMaxRetries) {
366 ++retries_count_; 375 ++retries_count_;
367 return true; 376 if (type_ == DeviceManagementRequestJob::TYPE_POLICY_FETCH) {
377 // We must not delay when retrying policy fetch, because it is a blocking
378 // call when logging in.
379 return RETRY_IMMEDIATELY;
380 } else {
381 return RETRY_WITH_DELAY;
382 }
368 } 383 }
369 384
370 // The request didn't fail, or the limit of retry attempts has been reached; 385 // The request didn't fail, or the limit of retry attempts has been reached;
371 // forward the result to the job owner. 386 // forward the result to the job owner.
372 return false; 387 return NO_RETRY;
388 }
389
390 int DeviceManagementRequestJobImpl::GetRetryDelay(RetryMethod method) {
391 switch (method) {
392 case RETRY_WITH_DELAY:
393 return g_retry_delay_ms << (retries_count_ - 1);
394 case RETRY_IMMEDIATELY:
395 return 0;
396 default:
397 NOTREACHED();
398 return 0;
399 }
373 } 400 }
374 401
375 void DeviceManagementRequestJobImpl::PrepareRetry() { 402 void DeviceManagementRequestJobImpl::PrepareRetry() {
376 if (!retry_callback_.is_null()) 403 if (!retry_callback_.is_null())
377 retry_callback_.Run(this); 404 retry_callback_.Run(this);
378 } 405 }
379 406
380 void DeviceManagementRequestJobImpl::ReportError(DeviceManagementStatus code) { 407 void DeviceManagementRequestJobImpl::ReportError(DeviceManagementStatus code) {
381 em::DeviceManagementResponse dummy_response; 408 em::DeviceManagementResponse dummy_response;
382 callback_.Run(code, net::OK, dummy_response); 409 callback_.Run(code, net::OK, dummy_response);
(...skipping 17 matching lines...) Expand all
400 AddParameter(dm_protocol::kParamDeviceID, client_id); 427 AddParameter(dm_protocol::kParamDeviceID, client_id);
401 } 428 }
402 429
403 em::DeviceManagementRequest* DeviceManagementRequestJob::GetRequest() { 430 em::DeviceManagementRequest* DeviceManagementRequestJob::GetRequest() {
404 return &request_; 431 return &request_;
405 } 432 }
406 433
407 DeviceManagementRequestJob::DeviceManagementRequestJob( 434 DeviceManagementRequestJob::DeviceManagementRequestJob(
408 JobType type, 435 JobType type,
409 const std::string& agent_parameter, 436 const std::string& agent_parameter,
410 const std::string& platform_parameter) { 437 const std::string& platform_parameter)
438 : type_(type) {
411 AddParameter(dm_protocol::kParamRequest, JobTypeToRequestType(type)); 439 AddParameter(dm_protocol::kParamRequest, JobTypeToRequestType(type));
412 AddParameter(dm_protocol::kParamDeviceType, dm_protocol::kValueDeviceType); 440 AddParameter(dm_protocol::kParamDeviceType, dm_protocol::kValueDeviceType);
413 AddParameter(dm_protocol::kParamAppType, dm_protocol::kValueAppType); 441 AddParameter(dm_protocol::kParamAppType, dm_protocol::kValueAppType);
414 AddParameter(dm_protocol::kParamAgent, agent_parameter); 442 AddParameter(dm_protocol::kParamAgent, agent_parameter);
415 AddParameter(dm_protocol::kParamPlatform, platform_parameter); 443 AddParameter(dm_protocol::kParamPlatform, platform_parameter);
416 } 444 }
417 445
418 void DeviceManagementRequestJob::SetRetryCallback( 446 void DeviceManagementRequestJob::SetRetryCallback(
419 const RetryCallback& retry_callback) { 447 const RetryCallback& retry_callback) {
420 retry_callback_ = retry_callback; 448 retry_callback_ = retry_callback;
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 const net::URLFetcher* source) { 563 const net::URLFetcher* source) {
536 JobFetcherMap::iterator entry(pending_jobs_.find(source)); 564 JobFetcherMap::iterator entry(pending_jobs_.find(source));
537 if (entry == pending_jobs_.end()) { 565 if (entry == pending_jobs_.end()) {
538 NOTREACHED() << "Callback from foreign URL fetcher"; 566 NOTREACHED() << "Callback from foreign URL fetcher";
539 return; 567 return;
540 } 568 }
541 569
542 DeviceManagementRequestJobImpl* job = entry->second; 570 DeviceManagementRequestJobImpl* job = entry->second;
543 pending_jobs_.erase(entry); 571 pending_jobs_.erase(entry);
544 572
545 if (job->ShouldRetry(source)) { 573 DeviceManagementRequestJobImpl::RetryMethod retry_method =
574 job->ShouldRetry(source);
575 if (retry_method != DeviceManagementRequestJobImpl::RetryMethod::NO_RETRY) {
546 job->PrepareRetry(); 576 job->PrepareRetry();
547 int delay = g_retry_delay_ms << (job->retries_count() - 1); 577 int delay = job->GetRetryDelay(retry_method);
548 LOG(WARNING) << "Dmserver request failed, retrying in " << delay / 1000 578 LOG(WARNING) << "Dmserver request failed, retrying in " << delay / 1000
549 << "s."; 579 << "s.";
550 task_runner_->PostDelayedTask( 580 task_runner_->PostDelayedTask(
551 FROM_HERE, 581 FROM_HERE,
552 base::Bind(&DeviceManagementService::StartJobAfterDelay, 582 base::Bind(&DeviceManagementService::StartJobAfterDelay,
553 weak_ptr_factory_.GetWeakPtr(), job->GetWeakPtr()), 583 weak_ptr_factory_.GetWeakPtr(), job->GetWeakPtr()),
554 base::TimeDelta::FromMilliseconds(delay)); 584 base::TimeDelta::FromMilliseconds(delay));
555 } else { 585 } else {
556 std::string data; 586 std::string data;
557 source->GetResponseAsString(&data); 587 source->GetResponseAsString(&data);
(...skipping 20 matching lines...) Expand all
578 } 608 }
579 } 609 }
580 610
581 const JobQueue::iterator elem = 611 const JobQueue::iterator elem =
582 std::find(queued_jobs_.begin(), queued_jobs_.end(), job); 612 std::find(queued_jobs_.begin(), queued_jobs_.end(), job);
583 if (elem != queued_jobs_.end()) 613 if (elem != queued_jobs_.end())
584 queued_jobs_.erase(elem); 614 queued_jobs_.erase(elem);
585 } 615 }
586 616
587 } // namespace policy 617 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698