Commit c498d38e authored by Marc Treib's avatar Marc Treib Committed by Commit Bot

Various small cleanups in ModelAssociationManager

Tightening up DCHECKs, removing dead code paths, updating comments.

Bug: 647505
Change-Id: I76dab7a9da0cf02252e545f2c839e4079d2270d3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2470084
Commit-Queue: Marc Treib <treib@chromium.org>
Reviewed-by: default avatarJan Krcal <jkrcal@chromium.org>
Cr-Commit-Position: refs/heads/master@{#817067}
parent 1abc0d9f
...@@ -7,8 +7,7 @@ ...@@ -7,8 +7,7 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <algorithm> #include <map>
#include <functional>
#include <utility> #include <utility>
#include "base/barrier_closure.h" #include "base/barrier_closure.h"
...@@ -16,10 +15,7 @@ ...@@ -16,10 +15,7 @@
#include "base/bind_helpers.h" #include "base/bind_helpers.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_functions.h"
#include "base/stl_util.h"
#include "base/trace_event/trace_event.h"
#include "components/sync/base/model_type.h" #include "components/sync/base/model_type.h"
#include "components/sync/base/sync_stop_metadata_fate.h"
namespace syncer { namespace syncer {
...@@ -62,9 +58,9 @@ const int64_t kAssociationTimeOutInSeconds = 600; ...@@ -62,9 +58,9 @@ const int64_t kAssociationTimeOutInSeconds = 600;
ModelAssociationManager::ModelAssociationManager( ModelAssociationManager::ModelAssociationManager(
const DataTypeController::TypeMap* controllers, const DataTypeController::TypeMap* controllers,
ModelAssociationManagerDelegate* processor) ModelAssociationManagerDelegate* processor)
: state_(IDLE), : controllers_(controllers),
controllers_(controllers),
delegate_(processor), delegate_(processor),
state_(IDLE),
configure_status_(DataTypeManager::UNKNOWN), configure_status_(DataTypeManager::UNKNOWN),
notified_about_ready_for_configure_(false) {} notified_about_ready_for_configure_(false) {}
...@@ -90,7 +86,7 @@ void ModelAssociationManager::Initialize(ModelTypeSet desired_types, ...@@ -90,7 +86,7 @@ void ModelAssociationManager::Initialize(ModelTypeSet desired_types,
for (ModelType type : desired_types) { for (ModelType type : desired_types) {
auto dtc_iter = controllers_->find(type); auto dtc_iter = controllers_->find(type);
if (dtc_iter != controllers_->end()) { if (dtc_iter != controllers_->end()) {
DataTypeController* dtc = dtc_iter->second.get(); const DataTypeController* dtc = dtc_iter->second.get();
// Controllers in a FAILED state should have been filtered out by the // Controllers in a FAILED state should have been filtered out by the
// DataTypeManager. // DataTypeManager.
DCHECK_NE(dtc->state(), DataTypeController::FAILED); DCHECK_NE(dtc->state(), DataTypeController::FAILED);
...@@ -132,12 +128,12 @@ void ModelAssociationManager::Initialize(ModelTypeSet desired_types, ...@@ -132,12 +128,12 @@ void ModelAssociationManager::Initialize(ModelTypeSet desired_types,
} }
} }
// Run LoadEnabledTypes() only after all relevant types are stopped. // Run LoadDesiredTypes() only after all relevant types are stopped.
// TODO(mastiz): Add test coverage to this waiting logic, including the // TODO(mastiz): Add test coverage to this waiting logic, including the
// case where the datatype is STOPPING when this function is called. // case where the datatype is STOPPING when this function is called.
base::RepeatingClosure barrier_closure = base::BarrierClosure( base::RepeatingClosure barrier_closure = base::BarrierClosure(
types_to_stop.size(), types_to_stop.size(),
base::BindOnce(&ModelAssociationManager::LoadEnabledTypes, base::BindOnce(&ModelAssociationManager::LoadDesiredTypes,
weak_ptr_factory_.GetWeakPtr())); weak_ptr_factory_.GetWeakPtr()));
for (const auto& dtc_and_reason : types_to_stop) { for (const auto& dtc_and_reason : types_to_stop) {
...@@ -183,7 +179,7 @@ void ModelAssociationManager::StopDatatypeImpl( ...@@ -183,7 +179,7 @@ void ModelAssociationManager::StopDatatypeImpl(
dtc->Stop(shutdown_reason, std::move(callback)); dtc->Stop(shutdown_reason, std::move(callback));
} }
void ModelAssociationManager::LoadEnabledTypes() { void ModelAssociationManager::LoadDesiredTypes() {
// Load in kStartOrder. // Load in kStartOrder.
for (ModelType type : kStartOrder) { for (ModelType type : kStartOrder) {
if (!desired_types_.Has(type)) if (!desired_types_.Has(type))
...@@ -235,14 +231,8 @@ void ModelAssociationManager::StartAssociationAsync( ...@@ -235,14 +231,8 @@ void ModelAssociationManager::StartAssociationAsync(
// Associate types that are already loaded in specified order. // Associate types that are already loaded in specified order.
for (ModelType type : kStartOrder) { for (ModelType type : kStartOrder) {
if (!associating_types_.Has(type) || !loaded_types_.Has(type)) if (associating_types_.Has(type) && loaded_types_.Has(type))
continue; MarkDataTypeAssociationDone(type);
DataTypeController* dtc = controllers_->find(type)->second.get();
TRACE_EVENT_ASYNC_BEGIN1("sync", "ModelAssociation", dtc, "DataType",
ModelTypeToString(type));
MarkDataTypeAssociationDone(type);
} }
} }
...@@ -269,7 +259,6 @@ void ModelAssociationManager::Stop(ShutdownReason shutdown_reason) { ...@@ -269,7 +259,6 @@ void ModelAssociationManager::Stop(ShutdownReason shutdown_reason) {
if (state_ == ASSOCIATING) { if (state_ == ASSOCIATING) {
if (configure_status_ == DataTypeManager::OK) if (configure_status_ == DataTypeManager::OK)
configure_status_ = DataTypeManager::ABORTED; configure_status_ = DataTypeManager::ABORTED;
DVLOG(1) << "ModelAssociationManager: Calling OnModelAssociationDone";
ModelAssociationDone(IDLE); ModelAssociationDone(IDLE);
} else { } else {
DCHECK(associating_types_.Empty()); DCHECK(associating_types_.Empty());
...@@ -301,12 +290,12 @@ void ModelAssociationManager::ModelLoadCallback(ModelType type, ...@@ -301,12 +290,12 @@ void ModelAssociationManager::ModelLoadCallback(ModelType type,
loaded_types_.Put(type); loaded_types_.Put(type);
NotifyDelegateIfReadyForConfigure(); NotifyDelegateIfReadyForConfigure();
if (associating_types_.Has(type)) { if (associating_types_.Has(type)) {
DataTypeController* dtc = controllers_->find(type)->second.get(); const DataTypeController* dtc = controllers_->find(type)->second.get();
// If initial sync was done for this datatype then // If initial sync was done for this datatype then
// NotifyDelegateIfReadyForConfigure possibly already triggered model // NotifyDelegateIfReadyForConfigure possibly already triggered model
// association and StartAssociating was already called for this type. To // association and StartAssociating was already called for this type. To
// ensure StartAssociating is called only once only make a call if state is // ensure StartAssociating is called only once only make a call if state is
// MODEL_LOADED. // MODEL_LOADED (i.e. not RUNNING yet).
// TODO(pavely): Add test for this scenario in DataTypeManagerImpl // TODO(pavely): Add test for this scenario in DataTypeManagerImpl
// unittests. // unittests.
// TODO(crbug.com/647505): The above sounds quite broken (will // TODO(crbug.com/647505): The above sounds quite broken (will
...@@ -320,41 +309,25 @@ void ModelAssociationManager::ModelLoadCallback(ModelType type, ...@@ -320,41 +309,25 @@ void ModelAssociationManager::ModelLoadCallback(ModelType type,
} }
void ModelAssociationManager::MarkDataTypeAssociationDone(ModelType type) { void ModelAssociationManager::MarkDataTypeAssociationDone(ModelType type) {
DCHECK_EQ(state_, ASSOCIATING);
DCHECK(desired_types_.Has(type)); DCHECK(desired_types_.Has(type));
DCHECK(associating_types_.Has(type)); DCHECK(associating_types_.Has(type));
DCHECK(loaded_types_.Has(type)); DCHECK(loaded_types_.Has(type));
DCHECK(!associated_types_.Has(type)); DCHECK(!associated_types_.Has(type));
associated_types_.Put(type); associated_types_.Put(type);
associating_types_.Remove(type);
// TODO(crbug.com/647505): Should we check this *before* adding the type to
// |associated_types_|?
if (state_ != ASSOCIATING)
return;
TRACE_EVENT_ASYNC_END1("sync", "ModelAssociation",
controllers_->find(type)->second.get(), "DataType",
ModelTypeToString(type));
// Track the merge results if we succeeded or an association failure
// occurred.
if (ProtocolTypes().Has(type)) if (ProtocolTypes().Has(type))
delegate_->OnSingleDataTypeAssociationDone(type); delegate_->OnSingleDataTypeAssociationDone(type);
associating_types_.Remove(type);
if (associating_types_.Empty()) if (associating_types_.Empty())
ModelAssociationDone(INITIALIZED); ModelAssociationDone(INITIALIZED);
} }
void ModelAssociationManager::ModelAssociationDone(State new_state) { void ModelAssociationManager::ModelAssociationDone(State new_state) {
DCHECK_NE(IDLE, state_); DCHECK_EQ(ASSOCIATING, state_);
DCHECK_NE(ASSOCIATING, new_state);
if (state_ == INITIALIZED) {
// No associations are currently happening. Just reset the state.
state_ = new_state;
return;
}
DVLOG(1) << "Model association complete for " DVLOG(1) << "Model association complete for "
<< ModelTypeSetToString(requested_types_); << ModelTypeSetToString(requested_types_);
...@@ -395,11 +368,9 @@ void ModelAssociationManager::NotifyDelegateIfReadyForConfigure() { ...@@ -395,11 +368,9 @@ void ModelAssociationManager::NotifyDelegateIfReadyForConfigure() {
if (notified_about_ready_for_configure_) if (notified_about_ready_for_configure_)
return; return;
for (ModelType type : desired_types_) { if (!loaded_types_.HasAll(desired_types_)) {
if (!loaded_types_.Has(type)) { // At least one type is not ready.
// At least one type is not ready. return;
return;
}
} }
notified_about_ready_for_configure_ = true; notified_about_ready_for_configure_ = true;
......
...@@ -21,23 +21,13 @@ namespace syncer { ...@@ -21,23 +21,13 @@ namespace syncer {
struct ConfigureContext; struct ConfigureContext;
// TODO(crbug.com/1102837): Association was a Directory concept, this class // Interface for ModelAssociationManager to pass the results of async operations
// should disappear or be refactored. // back to DataTypeManager.
//
// |ModelAssociationManager| does the heavy lifting for doing the actual model
// association. It instructs DataTypeControllers to load models, start
// associating and stopping. Since the operations are async it uses an
// interface to inform DataTypeManager the results of the operations.
// This class is owned by DataTypeManager.
// |ModelAssociationManager| association functions are async. The results of
// those operations are passed back via this interface.
class ModelAssociationManagerDelegate { class ModelAssociationManagerDelegate {
public: public:
// Called when all desired types are ready to be configured with // Called when all desired types are loaded, i.e. are ready to be configured
// ModelTypeConfigurer. Data type is ready when its progress marker is // with ModelTypeConfigurer. A data type is ready when its progress marker is
// available to configurer. Directory data types are always ready, their // available, which is the case once the local model has been loaded.
// progress markers are read from directory. USS data type controllers need to
// load model and read data type context first.
// This function is called at most once after each call to // This function is called at most once after each call to
// ModelAssociationManager::Initialize(). // ModelAssociationManager::Initialize().
virtual void OnAllDataTypesReadyForConfigure() = 0; virtual void OnAllDataTypesReadyForConfigure() = 0;
...@@ -47,8 +37,8 @@ class ModelAssociationManagerDelegate { ...@@ -47,8 +37,8 @@ class ModelAssociationManagerDelegate {
virtual void OnSingleDataTypeAssociationDone(ModelType type) = 0; virtual void OnSingleDataTypeAssociationDone(ModelType type) = 0;
// Called when the ModelAssociationManager has decided it must stop |type|, // Called when the ModelAssociationManager has decided it must stop |type|,
// likely because it is no longer a desired data type or sync is shutting // likely because it is no longer a desired data type, sync is shutting down,
// down. // or some error occurred during loading.
virtual void OnSingleDataTypeWillStop(ModelType type, virtual void OnSingleDataTypeWillStop(ModelType type,
const SyncError& error) = 0; const SyncError& error) = 0;
...@@ -56,9 +46,15 @@ class ModelAssociationManagerDelegate { ...@@ -56,9 +46,15 @@ class ModelAssociationManagerDelegate {
// association for all desired types and has nothing left to do. // association for all desired types and has nothing left to do.
virtual void OnModelAssociationDone( virtual void OnModelAssociationDone(
const DataTypeManager::ConfigureResult& result) = 0; const DataTypeManager::ConfigureResult& result) = 0;
virtual ~ModelAssociationManagerDelegate() {}
virtual ~ModelAssociationManagerDelegate() = default;
}; };
// |ModelAssociationManager| instructs DataTypeControllers to load models and
// to stop (DataTypeManager is responsible for activating/deactivating data
// types). Since the operations are async it uses an interface to inform
// DataTypeManager of the results of the operations.
// This class is owned by DataTypeManager.
// TODO(crbug.com/1102837): Association was a Directory concept, this class // TODO(crbug.com/1102837): Association was a Directory concept, this class
// should disappear or be refactored. // should disappear or be refactored.
class ModelAssociationManager { class ModelAssociationManager {
...@@ -78,14 +74,13 @@ class ModelAssociationManager { ...@@ -78,14 +74,13 @@ class ModelAssociationManager {
ModelAssociationManagerDelegate* delegate); ModelAssociationManagerDelegate* delegate);
virtual ~ModelAssociationManager(); virtual ~ModelAssociationManager();
// Initializes the state to do the model association in future. This // Stops any data types that are *not* in |desired_types|, then kicks off
// should be called before communicating with sync server. A subsequent call // loading of all |desired_types|. A subsequent Initialize() call is only
// of Initialize is only allowed if the ModelAssociationManager has invoked // allowed after the ModelAssociationManager has invoked
// |OnModelAssociationDone| on the |ModelAssociationManagerDelegate|. After // OnModelAssociationDone() on the delegate. After this call, there should be
// this call, there should be several calls to StartAssociationAsync() // several calls to StartAssociationAsync() to associate subsets of
// to associate subset of |desired_types| which must be a subset of // |desired_types|, which itself must be a subset of |preferred_types|.
// |preferred_types|. // |preferred_types| contains all types selected by the user.
// |preferred_types| contains types selected by user.
void Initialize(ModelTypeSet desired_types, void Initialize(ModelTypeSet desired_types,
ModelTypeSet preferred_types, ModelTypeSet preferred_types,
const ConfigureContext& context); const ConfigureContext& context);
...@@ -110,10 +105,10 @@ class ModelAssociationManager { ...@@ -110,10 +105,10 @@ class ModelAssociationManager {
private: private:
// Start loading non-running types that are in |desired_types_|. // Start loading non-running types that are in |desired_types_|.
void LoadEnabledTypes(); void LoadDesiredTypes();
// Callback that will be invoked when the models finish loading. This callback // Callback that will be invoked when the model for |type| finishes loading.
// will be passed to |LoadModels| function. // This callback is passed to |LoadModels| function.
void ModelLoadCallback(ModelType type, const SyncError& error); void ModelLoadCallback(ModelType type, const SyncError& error);
void MarkDataTypeAssociationDone(ModelType type); void MarkDataTypeAssociationDone(ModelType type);
...@@ -129,13 +124,17 @@ class ModelAssociationManager { ...@@ -129,13 +124,17 @@ class ModelAssociationManager {
DataTypeController* dtc, DataTypeController* dtc,
DataTypeController::StopCallback callback); DataTypeController::StopCallback callback);
// Calls delegate's OnAllDataTypesReadyForConfigure when all datatypes from // Calls delegate's OnAllDataTypesReadyForConfigure if all datatypes from
// desired_types_ are ready for configure. Ensures that for every call to // |desired_types_| are loaded. Ensures that OnAllDataTypesReadyForConfigure
// Initialize callback is called at most once. // is called at most once for every call to Initialize().
// Datatype is ready if either it doesn't require LoadModels before configure
// or LoadModels successfully finished.
void NotifyDelegateIfReadyForConfigure(); void NotifyDelegateIfReadyForConfigure();
// Set of all registered controllers.
const DataTypeController::TypeMap* const controllers_;
// The delegate in charge of handling model association results.
ModelAssociationManagerDelegate* const delegate_;
State state_; State state_;
ConfigureContext configure_context_; ConfigureContext configure_context_;
...@@ -143,11 +142,12 @@ class ModelAssociationManager { ...@@ -143,11 +142,12 @@ class ModelAssociationManager {
// Data types that are enabled. // Data types that are enabled.
ModelTypeSet desired_types_; ModelTypeSet desired_types_;
// Data types that are requested to associate. // Data types that are requested to associate. Non-empty iff |state_| is
// ASSOCIATING.
ModelTypeSet requested_types_; ModelTypeSet requested_types_;
// Data types currently being associated, including types waiting for model // Data types currently being associated, including types still waiting for
// load. // model load. Non-empty iff |state_| is ASSOCIATING.
ModelTypeSet associating_types_; ModelTypeSet associating_types_;
// Data types that are loaded, i.e. ready to associate. // Data types that are loaded, i.e. ready to associate.
...@@ -157,13 +157,8 @@ class ModelAssociationManager { ...@@ -157,13 +157,8 @@ class ModelAssociationManager {
// reconfiguration if not disabled. // reconfiguration if not disabled.
ModelTypeSet associated_types_; ModelTypeSet associated_types_;
// Set of all registered controllers. // Timer to track and limit how long a data type still takes to load after
const DataTypeController::TypeMap* controllers_; // StartAssociationAsync is called.
// The processor in charge of handling model association results.
ModelAssociationManagerDelegate* delegate_;
// Timer to track and limit how long a datatype takes to model associate.
base::OneShotTimer timer_; base::OneShotTimer timer_;
DataTypeManager::ConfigureStatus configure_status_; DataTypeManager::ConfigureStatus configure_status_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment