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

Unified Diff: chrome/browser/sync/glue/model_association_manager.cc

Issue 10387144: [Sync] - Implement isolated model association. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: For submitting. Created 8 years, 7 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 side-by-side diff with in-line comments
Download patch
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 bd74db75890f8b7f8f2d0aa2e7e87b52bf222462..4ad5bfe190b77c5bbc77861cde515ded59a9c819 100644
--- a/chrome/browser/sync/glue/model_association_manager.cc
+++ b/chrome/browser/sync/glue/model_association_manager.cc
@@ -2,6 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <algorithm>
+#include <functional>
+
+#include "base/debug/trace_event.h"
+
+#include "base/logging.h"
+#include "base/message_loop.h"
+#include "base/metrics/histogram.h"
+
#include "chrome/browser/sync/glue/model_association_manager.h"
#include "content/public/browser/browser_thread.h"
@@ -19,6 +28,11 @@ using content::BrowserThread;
using syncable::ModelTypeSet;
namespace browser_sync {
+// The amount of time we wait for a datatype to load. If the type has
+// not finished loading we move on to the next type. Once this type
+// finishes loading we will do a configure to associate this type. Note
+// that in most cases types finish loading before this timeout.
+const int64 kDataTypeLoadWaitTimeInSeconds = 120;
namespace {
static const syncable::ModelType kStartOrder[] = {
@@ -94,6 +108,24 @@ void ModelAssociationManager::Initialize(
desired_types_ = desired_types;
state_ = INITIAILIZED_TO_CONFIGURE;
+ DVLOG(1) << "ModelAssociationManager: Initializing";
+
+ // 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) {
+ DVLOG(1) << "ModelAssociationManager: Stopping "
+ << (*it)->name()
+ << " before initialization";
+ (*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.
@@ -112,7 +144,7 @@ void ModelAssociationManager::Initialize(
dtc->state() == DataTypeController::RUNNING ||
dtc->state() == DataTypeController::DISABLED)) {
needs_stop_.push_back(dtc);
- DVLOG(1) << "Will stop " << dtc->name();
+ DVLOG(1) << "ModelTypeToString: Will stop " << dtc->name();
}
}
// Sort these according to kStartOrder.
@@ -124,12 +156,14 @@ void ModelAssociationManager::Initialize(
void ModelAssociationManager::StartAssociationAsync() {
DCHECK_EQ(state_, INITIAILIZED_TO_CONFIGURE);
state_ = CONFIGURING;
+ DVLOG(1) << "ModelAssociationManager: Going to start model association";
LoadModelForNextType();
}
void ModelAssociationManager::ResetForReconfiguration() {
DCHECK_EQ(state_, INITIAILIZED_TO_CONFIGURE);
state_ = IDLE;
+ DVLOG(1) << "ModelAssociationManager: Reseting for reconfiguration";
needs_start_.clear();
needs_stop_.clear();
failed_datatypes_info_.clear();
@@ -137,9 +171,10 @@ void ModelAssociationManager::ResetForReconfiguration() {
void ModelAssociationManager::StopDisabledTypes() {
DCHECK_EQ(state_, INITIAILIZED_TO_CONFIGURE);
+ DVLOG(1) << "ModelAssociationManager: Stopping disabled types.";
// Stop requested data types.
for (size_t i = 0; i < needs_stop_.size(); ++i) {
- DVLOG(1) << "Stopping " << needs_stop_[i]->name();
+ DVLOG(1) << "ModelAssociationManager: Stopping " << needs_stop_[i]->name();
needs_stop_[i]->Stop();
}
needs_stop_.clear();
@@ -147,7 +182,10 @@ void ModelAssociationManager::StopDisabledTypes() {
void ModelAssociationManager::Stop() {
bool need_to_call_model_association_done = false;
+ DVLOG(1) << "ModelAssociationManager: Stopping MAM";
if (state_ == CONFIGURING) {
+ DVLOG(1) << "ModelAssociationManager: In the middle of configuratio while"
+ << " stopping";
state_ = ABORTED;
DCHECK(currently_associating_ != NULL ||
needs_start_.size() > 0 ||
@@ -155,6 +193,8 @@ void ModelAssociationManager::Stop() {
waiting_to_associate_.size() > 0);
if (currently_associating_) {
+ DVLOG(1) << "ModelAssociationManager: stopping "
+ << currently_associating_->name();
currently_associating_->Stop();
} else {
// DTCs in other lists would be stopped below.
@@ -177,14 +217,16 @@ void ModelAssociationManager::Stop() {
if (dtc->state() != DataTypeController::NOT_RUNNING &&
dtc->state() != DataTypeController::STOPPING) {
dtc->Stop();
- DVLOG(1) << "Stopped " << dtc->name();
+ DVLOG(1) << "ModelAssociationManager: Stopped " << dtc->name();
}
}
if (need_to_call_model_association_done) {
+ DVLOG(1) << "ModelAssociationManager: Calling OnModelAssociationDone";
DataTypeManager::ConfigureResult result(DataTypeManager::ABORTED,
desired_types_,
- failed_datatypes_info_);
+ failed_datatypes_info_,
+ syncable::ModelTypeSet());
result_processor_->OnModelAssociationDone(result);
}
@@ -193,6 +235,7 @@ void ModelAssociationManager::Stop() {
bool ModelAssociationManager::GetControllersNeedingStart(
std::vector<DataTypeController*>* needs_start) {
+ DVLOG(1) << "ModelAssociationManager: GetControllersNeedingStart";
// Add any data type controllers into the needs_start_ list that are
// currently NOT_RUNNING or STOPPING.
bool found_any = false;
@@ -207,7 +250,8 @@ bool ModelAssociationManager::GetControllersNeedingStart(
if (needs_start)
needs_start->push_back(dtc->second.get());
if (dtc->second->state() == DataTypeController::DISABLED) {
- DVLOG(1) << "Found " << syncable::ModelTypeToString(dtc->second->type())
+ DVLOG(1) << "ModelAssociationManager: Found "\
+ << syncable::ModelTypeToString(dtc->second->type())
<< " in disabled state.";
}
}
@@ -215,14 +259,28 @@ bool ModelAssociationManager::GetControllersNeedingStart(
return found_any;
}
+void ModelAssociationManager::AppendToFailedDatatypesAndLogError(
+ 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) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DVLOG(1) << "ModelAssociationManager: TypeStartCallback";
if (state_ == ABORTED) {
// Now that we have finished with the current type we can stop
// if abort was called.
+ DVLOG(1) << "ModelAssociationManager: Doing an early return"
+ << " because of abort";
state_ = IDLE;
return;
}
@@ -234,12 +292,8 @@ 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);
+ DVLOG(1) << "ModelAssociationManager: Encountered a failed type";
+ AppendToFailedDatatypesAndLogError(result, error);
}
// If the type started normally, continue to the next type.
@@ -250,6 +304,8 @@ void ModelAssociationManager::TypeStartCallback(
result == DataTypeController::OK ||
result == DataTypeController::OK_FIRST_RUN ||
result == DataTypeController::ASSOCIATION_FAILED) {
+ DVLOG(1) << "ModelAssociationManager: type start callback returned "
+ << result << " so calling LoadModelForNextType";
LoadModelForNextType();
return;
}
@@ -280,24 +336,34 @@ void ModelAssociationManager::TypeStartCallback(
DataTypeManager::ConfigureResult configure_result(configure_status,
desired_types_,
- errors);
+ errors,
+ syncable::ModelTypeSet());
result_processor_->OnModelAssociationDone(configure_result);
}
void ModelAssociationManager::LoadModelForNextType() {
+ DVLOG(1) << "ModelAssociationManager: LoadModelForNextType";
if (!needs_start_.empty()) {
- DVLOG(1) << "Starting " << needs_start_[0]->name();
+ DVLOG(1) << "ModelAssociationManager: Starting " << needs_start_[0]->name();
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::LoadModelForNextType);
dtc->LoadModels(base::Bind(
&ModelAssociationManager::ModelLoadCallback,
weak_ptr_factory_.GetWeakPtr()));
+
return;
}
+ DVLOG(1) << "ModelAssociationManager: All types have models loaded."
+ << "Moving on to StartAssociatingNextType.";
+
// If all controllers have their |LoadModels| invoked then pass onto
// |StartAssociatingNextType|.
StartAssociatingNextType();
@@ -305,37 +371,68 @@ 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);
+ DVLOG(1) << "ModelAssociationManager: ModelLoadCallback for "
+ << syncable::ModelTypeToString(type);
+ if (state_ == CONFIGURING) {
+ DVLOG(1) << "ModelAssociationManager: ModelLoadCallback while configuring";
+ for (std::vector<DataTypeController*>::iterator it =
+ pending_model_load_.begin();
+ it != pending_model_load_.end();
+ ++it) {
+ if ((*it)->type() == type) {
+ // Each type is given |kDataTypeLoadWaitTimeInSeconds| time to load
+ // (as controlled by the timer.). If the type does not load in that
+ // time we move on to the next type. However if the type does
+ // finish loading in that time we want to stop the timer. We stop
+ // the timer, if the type that loaded is the same as the type that
+ // we started the timer for(as indicated by the type on the head
+ // of the list).
+ // Note: Regardless of this timer value the associations will always
+ // take place serially. The only thing this timer controls is how serial
+ // the model load is. If this timer has a value of zero seconds then
+ // the model loads will all be parallel.
+ if (it == pending_model_load_.begin()) {
+ DVLOG(1) << "ModelAssociationManager: Stopping timer";
+ timer_.Stop();
+ }
+ DataTypeController* dtc = *it;
+ pending_model_load_.erase(it);
+ if (!error.IsSet()) {
+ DVLOG(1) << "ModelAssociationManager:"
+ << " Calling StartAssociatingNextType";
+ waiting_to_associate_.push_back(dtc);
+ StartAssociatingNextType();
+ } else {
+ DVLOG(1) << "ModelAssociationManager: Encountered error loading";
+ // Treat it like a regular error.
+ AppendToFailedDatatypesAndLogError(
+ DataTypeController::ASSOCIATION_FAILED,
+ error);
+ }
+ return;
}
- return;
}
+ NOTREACHED();
+ return;
+ } else {
+ DVLOG(1) << "ModelAssociationManager: Models loaded after configure cycle"
+ << "Informing DTM";
+ // This datatype finished loading after the deadline imposed by the
+ // originating configuration cycle. Inform the DataTypeManager that the
+ // type has loaded, so that association may begin.
+ result_processor_->OnTypesLoaded();
}
- NOTREACHED();
}
-
void ModelAssociationManager::StartAssociatingNextType() {
DCHECK_EQ(state_, CONFIGURING);
DCHECK_EQ(currently_associating_, static_cast<DataTypeController*>(NULL));
+
+ DVLOG(1) << "ModelAssociationManager: StartAssociatingNextType";
if (!waiting_to_associate_.empty()) {
- DVLOG(1) << "Starting " << waiting_to_associate_[0]->name();
+ DVLOG(1) << "ModelAssociationManager: Starting "
+ << waiting_to_associate_[0]->name();
TRACE_EVENT_BEGIN1("sync", "ModelAssociation",
"DataType",
ModelTypeToString(waiting_to_associate_[0]->type()));
@@ -354,28 +451,53 @@ void ModelAssociationManager::StartAssociatingNextType() {
// things like encryption, which may still need to be sorted out before we
// can announce we're "Done" configuration entirely.
if (GetControllersNeedingStart(NULL)) {
- DVLOG(1) << "GetControllersNeedingStart returned true."
- << " Blocking DataTypeManager";
+ DVLOG(1) << "ModelAssociationManager: GetControllersNeedingStart"
+ << " returned true. Blocking DataTypeManager";
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()) {
+ // We have not configured all types that we have been asked to configure.
+ // Either we have failed types or types that have not completed loading
+ // yet.
+ DVLOG(1) << "ModelAssociationManager: setting partial success";
configure_status = DataTypeManager::PARTIAL_SUCCESS;
+ }
DataTypeManager::ConfigureResult result(configure_status,
desired_types_,
- failed_datatypes_info_);
+ failed_datatypes_info_,
+ GetTypesWaitingToLoad());
result_processor_->OnModelAssociationDone(result);
return;
}
+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;
+}
+
+base::OneShotTimer<ModelAssociationManager>*
+ ModelAssociationManager::GetTimerForTesting() {
+ return &timer_;
+}
+
} // namespace browser_sync
« no previous file with comments | « chrome/browser/sync/glue/model_association_manager.h ('k') | chrome/browser/sync/glue/model_association_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698