| Index: trunk/src/components/sync_driver/data_type_manager_impl.cc
|
| ===================================================================
|
| --- trunk/src/components/sync_driver/data_type_manager_impl.cc (revision 289352)
|
| +++ trunk/src/components/sync_driver/data_type_manager_impl.cc (working copy)
|
| @@ -88,7 +88,9 @@
|
| if (syncer::IsControlType(type.Get()) ||
|
| iter != controllers_->end()) {
|
| if (iter != controllers_->end()) {
|
| - if (!iter->second->ReadyForStart()) {
|
| + if (!iter->second->ReadyForStart() &&
|
| + !failed_data_types_handler_->GetUnreadyErrorTypes().Has(
|
| + type.Get())) {
|
| // Add the type to the unready types set to prevent purging it. It's
|
| // up to the datatype controller to, if necessary, explicitly
|
| // mark the type as broken to trigger a purge.
|
| @@ -99,7 +101,7 @@
|
| std::map<syncer::ModelType, syncer::SyncError> errors;
|
| errors[type.Get()] = error;
|
| failed_data_types_handler_->UpdateFailedDataTypes(errors);
|
| - } else {
|
| + } else if (iter->second->ReadyForStart()) {
|
| failed_data_types_handler_->ResetUnreadyErrorFor(type.Get());
|
| }
|
| }
|
| @@ -345,14 +347,18 @@
|
| if (!failed_configuration_types.Empty()) {
|
| if (!unrecoverable_error_method_.is_null())
|
| unrecoverable_error_method_.Run();
|
| - std::string error_msg =
|
| - "Configuration failed for types " +
|
| - syncer::ModelTypeSetToString(failed_configuration_types);
|
| - syncer::SyncError error(FROM_HERE,
|
| - syncer::SyncError::UNRECOVERABLE_ERROR,
|
| - error_msg,
|
| - failed_configuration_types.First().Get());
|
| - Abort(UNRECOVERABLE_ERROR, error);
|
| + FailedDataTypesHandler::TypeErrorMap errors;
|
| + for (syncer::ModelTypeSet::Iterator iter =
|
| + failed_configuration_types.First(); iter.Good(); iter.Inc()) {
|
| + syncer::SyncError error(
|
| + FROM_HERE,
|
| + syncer::SyncError::UNRECOVERABLE_ERROR,
|
| + "Backend failed to download type.",
|
| + iter.Get());
|
| + errors[iter.Get()] = error;
|
| + }
|
| + failed_data_types_handler_->UpdateFailedDataTypes(errors);
|
| + Abort(UNRECOVERABLE_ERROR);
|
| return;
|
| }
|
|
|
| @@ -400,8 +406,24 @@
|
| }
|
|
|
| void DataTypeManagerImpl::OnSingleDataTypeWillStop(
|
| - syncer::ModelType type) {
|
| + syncer::ModelType type,
|
| + const syncer::SyncError& error) {
|
| configurer_->DeactivateDataType(type);
|
| + if (error.IsSet()) {
|
| + FailedDataTypesHandler::TypeErrorMap failed_types;
|
| + failed_types[type] = error;
|
| + failed_data_types_handler_->UpdateFailedDataTypes(
|
| + failed_types);
|
| +
|
| + // Unrecoverable errors will shut down the entire backend, so no need to
|
| + // reconfigure.
|
| + if (error.error_type() != syncer::SyncError::UNRECOVERABLE_ERROR) {
|
| + needs_reconfigure_ = true;
|
| + ProcessReconfigure();
|
| + } else {
|
| + DCHECK_EQ(state_, CONFIGURING);
|
| + }
|
| + }
|
| }
|
|
|
| void DataTypeManagerImpl::OnSingleDataTypeAssociationDone(
|
| @@ -449,25 +471,6 @@
|
| if (state_ == STOPPING)
|
| return;
|
|
|
| - // Don't reconfigure due to failed data types if we have an unrecoverable
|
| - // error or have already aborted.
|
| - if (result.status == PARTIAL_SUCCESS) {
|
| - if (!result.needs_crypto.Empty()) {
|
| - needs_reconfigure_ = true;
|
| - syncer::ModelTypeSet encrypted_types = result.needs_crypto;
|
| - encrypted_types.RemoveAll(
|
| - failed_data_types_handler_->GetCryptoErrorTypes());
|
| - FailedDataTypesHandler::TypeErrorMap crypto_errors =
|
| - GenerateCryptoErrorsForTypes(encrypted_types);
|
| - failed_data_types_handler_->UpdateFailedDataTypes(crypto_errors);
|
| - }
|
| - if (!result.failed_data_types.empty()) {
|
| - needs_reconfigure_ = true;
|
| - failed_data_types_handler_->UpdateFailedDataTypes(
|
| - result.failed_data_types);
|
| - }
|
| - }
|
| -
|
| // Ignore abort/unrecoverable error if we need to reconfigure anyways.
|
| if (needs_reconfigure_) {
|
| association_types_queue_ = std::queue<AssociationTypesInfo>();
|
| @@ -476,38 +479,18 @@
|
| }
|
|
|
| if (result.status == ABORTED || result.status == UNRECOVERABLE_ERROR) {
|
| - Abort(result.status, result.failed_data_types.size() >= 1 ?
|
| - result.failed_data_types.begin()->second :
|
| - syncer::SyncError());
|
| + Abort(result.status);
|
| return;
|
| }
|
|
|
| - DCHECK(result.status == PARTIAL_SUCCESS || result.status == OK);
|
| - DCHECK(result.status != OK ||
|
| - (result.needs_crypto.Empty() && result.failed_data_types.empty()));
|
| + DCHECK(result.status == OK);
|
|
|
| - // It's possible this is a retry to disable failed types, in which case
|
| - // the association would be SUCCESS, but the overall configuration should
|
| - // still be PARTIAL_SUCCESS.
|
| - syncer::ModelTypeSet failed_data_types =
|
| - failed_data_types_handler_->GetFailedTypes();
|
| - ConfigureStatus status = result.status;
|
| - if (!syncer::Intersection(last_requested_types_,
|
| - failed_data_types).Empty() && result.status == OK) {
|
| - status = PARTIAL_SUCCESS;
|
| - }
|
| -
|
| association_types_queue_.pop();
|
| if (!association_types_queue_.empty()) {
|
| StartNextAssociation();
|
| } else if (download_types_queue_.empty()) {
|
| state_ = CONFIGURED;
|
| - ConfigureResult configure_result(status,
|
| - result.requested_types,
|
| - failed_data_types_handler_->GetAllErrors(),
|
| - result.unfinished_data_types,
|
| - result.needs_crypto);
|
| - NotifyDone(configure_result);
|
| + NotifyDone(result);
|
| }
|
| }
|
|
|
| @@ -521,29 +504,19 @@
|
|
|
| if (need_to_notify) {
|
| ConfigureResult result(ABORTED,
|
| - last_requested_types_,
|
| - std::map<syncer::ModelType, syncer::SyncError>(),
|
| - syncer::ModelTypeSet(),
|
| - syncer::ModelTypeSet());
|
| + last_requested_types_);
|
| NotifyDone(result);
|
| }
|
| }
|
|
|
| -void DataTypeManagerImpl::Abort(ConfigureStatus status,
|
| - const syncer::SyncError& error) {
|
| +void DataTypeManagerImpl::Abort(ConfigureStatus status) {
|
| DCHECK(state_ == DOWNLOAD_PENDING || state_ == CONFIGURING);
|
|
|
| StopImpl();
|
|
|
| DCHECK_NE(OK, status);
|
| - std::map<syncer::ModelType, syncer::SyncError> errors;
|
| - if (error.IsSet())
|
| - errors[error.model_type()] = error;
|
| ConfigureResult result(status,
|
| - last_requested_types_,
|
| - errors,
|
| - syncer::ModelTypeSet(),
|
| - syncer::ModelTypeSet());
|
| + last_requested_types_);
|
| NotifyDone(result);
|
| }
|
|
|
| @@ -593,12 +566,7 @@
|
| UMA_HISTOGRAM_LONG_TIMES("Sync.ConfigureTime_Long.UNRECOVERABLE_ERROR",
|
| configure_time_delta_);
|
| break;
|
| - case DataTypeManager::PARTIAL_SUCCESS:
|
| - DVLOG(1) << "NotifyDone called with result: PARTIAL_SUCCESS";
|
| - UMA_HISTOGRAM_LONG_TIMES("Sync.ConfigureTime_Long.PARTIAL_SUCCESS",
|
| - configure_time_delta_);
|
| - break;
|
| - default:
|
| + case DataTypeManager::UNKNOWN:
|
| NOTREACHED();
|
| break;
|
| }
|
|
|