Chromium Code Reviews| Index: chrome/browser/sync/glue/model_association_manager.cc |
| diff --git a/chrome/browser/sync/glue/model_association_manager.cc b/chrome/browser/sync/glue/model_association_manager.cc |
| index 18a5e14332f29360fe8f57990c527b340d3678ec..879078b47e4b7ae0257e14a4b7a2b6de0a67ed90 100755 |
| --- a/chrome/browser/sync/glue/model_association_manager.cc |
| +++ b/chrome/browser/sync/glue/model_association_manager.cc |
| @@ -19,6 +19,7 @@ using content::BrowserThread; |
| using syncable::ModelTypeSet; |
| namespace browser_sync { |
| +const int64 kDataTypeLoadWaitTimeInSeconds = 120; |
| namespace { |
| static const syncable::ModelType kStartOrder[] = { |
| @@ -94,6 +95,21 @@ void ModelAssociationManager::Initialize( |
| desired_types_ = desired_types; |
| state_ = INITIAILIZED_TO_CONFIGURE; |
| + // Stop the types that are still loading from the previous configuration. |
| + // If they are enabled we will start them here once again. |
| + |
| + for (std::vector<DataTypeController*>::const_iterator it = |
| + pending_model_load_.begin(); |
| + it != pending_model_load_.end(); |
| + ++it) { |
| + (*it)->Stop(); |
| + } |
| + |
| + pending_model_load_.clear(); |
| + waiting_to_associate_.clear(); |
| + currently_associating_ = NULL; |
| + |
| + |
| // We need to calculate our |needs_start_| and |needs_stop_| list. |
| GetControllersNeedingStart(&needs_start_); |
| // Sort these according to kStartOrder. |
| @@ -178,7 +194,8 @@ void ModelAssociationManager::Stop() { |
| if (need_to_call_model_association_done) { |
| DataTypeManager::ConfigureResult result(DataTypeManager::ABORTED, |
| desired_types_, |
| - failed_datatypes_info_); |
| + failed_datatypes_info_, |
| + syncable::ModelTypeSet()); |
| result_processor_->OnModelAssociationDone(result); |
| } |
| @@ -209,6 +226,18 @@ bool ModelAssociationManager::GetControllersNeedingStart( |
| return found_any; |
| } |
| +void ModelAssociationManager::HandleFailedTypes( |
| + DataTypeController::StartResult result, |
| + const SyncError& error) { |
| + failed_datatypes_info_.push_back(error); |
| + LOG(ERROR) << "Failed to associate models for " |
| + << syncable::ModelTypeToString(error.type()); |
| + UMA_HISTOGRAM_ENUMERATION("Sync.ConfigureFailed", |
| + error.type(), |
| + syncable::MODEL_TYPE_COUNT); |
| + |
| +} |
| + |
| void ModelAssociationManager::TypeStartCallback( |
| DataTypeController::StartResult result, |
| const SyncError& error) { |
| @@ -228,12 +257,7 @@ void ModelAssociationManager::TypeStartCallback( |
| currently_associating_ = NULL; |
| if (result == DataTypeController::ASSOCIATION_FAILED) { |
| - failed_datatypes_info_.push_back(error); |
| - LOG(ERROR) << "Failed to associate models for " |
| - << syncable::ModelTypeToString(error.type()); |
| - UMA_HISTOGRAM_ENUMERATION("Sync.ConfigureFailed", |
| - error.type(), |
| - syncable::MODEL_TYPE_COUNT); |
| + HandleFailedTypes(result, error); |
| } |
| // If the type started normally, continue to the next type. |
| @@ -274,7 +298,8 @@ void ModelAssociationManager::TypeStartCallback( |
| DataTypeManager::ConfigureResult configure_result(configure_status, |
| desired_types_, |
| - errors); |
| + errors, |
| + syncable::ModelTypeSet()); |
| result_processor_->OnModelAssociationDone(configure_result); |
| } |
| @@ -285,10 +310,15 @@ void ModelAssociationManager::LoadModelForNextType() { |
| DataTypeController* dtc = needs_start_[0]; |
| needs_start_.erase(needs_start_.begin()); |
| // Move from |needs_start_| to |pending_model_load_|. |
| - pending_model_load_.push_back(dtc); |
| + pending_model_load_.insert(pending_model_load_.begin(), dtc); |
| + timer_.Start(FROM_HERE, |
| + base::TimeDelta::FromSeconds(kDataTypeLoadWaitTimeInSeconds), |
| + this, |
| + &ModelAssociationManager::ModelLoadTimedOut); |
| dtc->LoadModels(base::Bind( |
| &ModelAssociationManager::ModelLoadCallback, |
| weak_ptr_factory_.GetWeakPtr())); |
| + |
| return; |
| } |
| @@ -299,29 +329,38 @@ void ModelAssociationManager::LoadModelForNextType() { |
| void ModelAssociationManager::ModelLoadCallback( |
| syncable::ModelType type, SyncError error) { |
| - DCHECK_EQ(state_, CONFIGURING); |
| - |
| - for (std::vector<DataTypeController*>::iterator it = |
| - pending_model_load_.begin(); |
| - it != pending_model_load_.end(); |
| - ++it) { |
| - if ((*it)->type() == type) { |
| - DataTypeController* dtc = *it; |
| - pending_model_load_.erase(it); |
| - if (!error.IsSet()) { |
| - waiting_to_associate_.push_back(dtc); |
| - StartAssociatingNextType(); |
| - } else { |
| - // Treat it like a regular error. |
| - DCHECK(currently_associating_ == NULL); |
| - currently_associating_ = dtc; |
| - TypeStartCallback(DataTypeController::ASSOCIATION_FAILED, error); |
| - } |
| - return; |
| + if (state_ == CONFIGURING) { |
| + for (std::vector<DataTypeController*>::iterator it = |
| + pending_model_load_.begin(); |
| + it != pending_model_load_.end(); |
| + ++it) { |
| + if ((*it)->type() == type) { |
| + // If the type that got loaded was the type that was started |
|
tim (not reviewing)
2012/05/21 23:18:57
'If the type that just finished loading was the la
lipalani1
2012/05/22 01:23:58
Done.
|
| + // last, then we could stop the timer. |
| + if (it == pending_model_load_.begin()) { |
| + timer_.Stop(); |
| + } |
| + DataTypeController* dtc = *it; |
| + pending_model_load_.erase(it); |
| + if (!error.IsSet()) { |
| + waiting_to_associate_.push_back(dtc); |
| + StartAssociatingNextType(); |
| + } else { |
| + // Treat it like a regular error. |
| + HandleFailedTypes(DataTypeController::ASSOCIATION_FAILED, error); |
| + } |
| + return; |
| + } |
| } |
| + NOTREACHED(); |
| + return; |
| + } |
| + else { |
| + // We got a callback on type that we started loading during the |
|
tim (not reviewing)
2012/05/21 23:18:57
"This data type finished loading after the deadlin
lipalani1
2012/05/22 01:23:58
Done.
|
| + // previous configuration. Inform the DTM that the type has loaded. |
| + result_processor_->OnTypesLoaded(); |
| } |
| - NOTREACHED(); |
| } |
| @@ -352,22 +391,47 @@ void ModelAssociationManager::StartAssociatingNextType() { |
| DataTypeManager::ConfigureResult configure_result( |
| DataTypeManager::CONFIGURE_BLOCKED, |
| desired_types_, |
| - failed_datatypes_info_); |
| + failed_datatypes_info_, |
| + syncable::ModelTypeSet()); |
| state_ = IDLE; |
| result_processor_->OnModelAssociationDone(configure_result); |
| return; |
| } |
| DataTypeManager::ConfigureStatus configure_status = DataTypeManager::OK; |
| - if (!failed_datatypes_info_.empty()) { |
| + if (!failed_datatypes_info_.empty() || |
| + !GetTypesWaitingToLoad().Empty()) { |
| configure_status = DataTypeManager::PARTIAL_SUCCESS; |
| } |
| DataTypeManager::ConfigureResult result(configure_status, |
| desired_types_, |
| - failed_datatypes_info_); |
| + failed_datatypes_info_, |
| + GetTypesWaitingToLoad()); |
| result_processor_->OnModelAssociationDone(result); |
| return; |
| } |
| +void ModelAssociationManager::ModelLoadTimedOut() { |
|
tim (not reviewing)
2012/05/21 23:18:57
Is this method actually needed?
lipalani1
2012/05/22 01:23:58
Just for clarity purpose... Compiler probably opti
tim (not reviewing)
2012/05/22 16:50:05
Hmm, to me the extra indirection makes it less cle
lipalani1
2012/05/22 20:20:46
Done.
|
| + LoadModelForNextType(); |
| +} |
| + |
| +syncable::ModelTypeSet ModelAssociationManager::GetTypesWaitingToLoad() { |
| + syncable::ModelTypeSet result; |
| + for (std::vector<DataTypeController*>::const_iterator it = |
| + pending_model_load_.begin(); |
| + it != pending_model_load_.end(); |
| + ++it) { |
| + result.Put((*it)->type()); |
| + } |
| + return result; |
| +} |
| + |
| +void ModelAssociationManager::TestSimulateDataTypeLoadTimeout() { |
|
tim (not reviewing)
2012/05/21 23:18:57
I think there is a way to do this that doesn't req
lipalani1
2012/05/22 01:23:58
I think the eventual direction you are advocating
tim (not reviewing)
2012/05/22 16:50:05
It sounds like we're in agreement that it would be
lipalani1
2012/05/22 20:20:46
I have addressed this. Let me know what you think.
|
| + timer_.Stop(); |
| + ModelLoadTimedOut(); |
| +} |
| + |
| + |
| + |
| } // namespace browser_sync |