Commit 970fd082 authored by Jan Krcal's avatar Jan Krcal Committed by Commit Bot

[USS] Uncouple ModelTypeControllerDelegate from bridges - part 1

This CL unblocks
https://chromium-review.googlesource.com/c/chromium/src/+/102589 that
separates the controller delegate interface from the bridges and makes
ClientTagBasedModelTypeProcessor directly implement the interface.

Since the processor needs to be able to inform the bridge that sync
is starting (before the bridge is ready to sync, i.e. before it gets
the pointer to the bridge), this CL passes the (preliminary) bridge
pointer to the processor during construction of the bridge.

This CL is admittedly hacky, it only minimizes the CL size and thus
the speed for landing the blocked CL. After the CL gets landed, we
need to remove this hack and introduce a proper solution, probably by
swapping the ownership of the bridge and the processor.

Bug: 819993
Change-Id: Ie1950e6626a3ab58a583d8fbe502ba52c34319e0
Reviewed-on: https://chromium-review.googlesource.com/1042707
Commit-Queue: Jan Krcal <jkrcal@chromium.org>
Reviewed-by: default avatarMikel Astiz <mastiz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#556793}
parent 1477d0b9
...@@ -44,6 +44,9 @@ void FakeModelTypeChangeProcessor::UpdateStorageKey( ...@@ -44,6 +44,9 @@ void FakeModelTypeChangeProcessor::UpdateStorageKey(
void FakeModelTypeChangeProcessor::UntrackEntity( void FakeModelTypeChangeProcessor::UntrackEntity(
const EntityData& entity_data) {} const EntityData& entity_data) {}
void FakeModelTypeChangeProcessor::OnModelStarting(
ModelTypeSyncBridge* bridge) {}
void FakeModelTypeChangeProcessor::ModelReadyToSync( void FakeModelTypeChangeProcessor::ModelReadyToSync(
ModelTypeSyncBridge* bridge, ModelTypeSyncBridge* bridge,
std::unique_ptr<MetadataBatch> batch) {} std::unique_ptr<MetadataBatch> batch) {}
......
...@@ -35,6 +35,7 @@ class FakeModelTypeChangeProcessor : public ModelTypeChangeProcessor { ...@@ -35,6 +35,7 @@ class FakeModelTypeChangeProcessor : public ModelTypeChangeProcessor {
const std::string& storage_key, const std::string& storage_key,
MetadataChangeList* metadata_change_list) override; MetadataChangeList* metadata_change_list) override;
void UntrackEntity(const EntityData& entity_data) override; void UntrackEntity(const EntityData& entity_data) override;
void OnModelStarting(ModelTypeSyncBridge* bridge) override;
void ModelReadyToSync(ModelTypeSyncBridge* bridge, void ModelReadyToSync(ModelTypeSyncBridge* bridge,
std::unique_ptr<MetadataBatch> batch) override; std::unique_ptr<MetadataBatch> batch) override;
void OnSyncStarting(const ModelErrorHandler& error_handler, void OnSyncStarting(const ModelErrorHandler& error_handler,
......
...@@ -44,6 +44,10 @@ class ForwardingModelTypeChangeProcessor : public ModelTypeChangeProcessor { ...@@ -44,6 +44,10 @@ class ForwardingModelTypeChangeProcessor : public ModelTypeChangeProcessor {
other_->UntrackEntity(entity_data); other_->UntrackEntity(entity_data);
} }
void OnModelStarting(ModelTypeSyncBridge* bridge) override {
other_->OnModelStarting(bridge);
}
void ModelReadyToSync(ModelTypeSyncBridge* bridge, void ModelReadyToSync(ModelTypeSyncBridge* bridge,
std::unique_ptr<MetadataBatch> batch) override { std::unique_ptr<MetadataBatch> batch) override {
other_->ModelReadyToSync(bridge, std::move(batch)); other_->ModelReadyToSync(bridge, std::move(batch));
...@@ -117,6 +121,9 @@ void MockModelTypeChangeProcessor::DelegateCallsByDefaultTo( ...@@ -117,6 +121,9 @@ void MockModelTypeChangeProcessor::DelegateCallsByDefaultTo(
ON_CALL(*this, UntrackEntity(_)) ON_CALL(*this, UntrackEntity(_))
.WillByDefault( .WillByDefault(
Invoke(delegate, &ModelTypeChangeProcessor::UntrackEntity)); Invoke(delegate, &ModelTypeChangeProcessor::UntrackEntity));
ON_CALL(*this, OnModelStarting(_))
.WillByDefault(
Invoke(delegate, &ModelTypeChangeProcessor::OnModelStarting));
ON_CALL(*this, DoModelReadyToSync(_, _)) ON_CALL(*this, DoModelReadyToSync(_, _))
.WillByDefault( .WillByDefault(
Invoke([delegate](ModelTypeSyncBridge* bridge, MetadataBatch* batch) { Invoke([delegate](ModelTypeSyncBridge* bridge, MetadataBatch* batch) {
......
...@@ -36,6 +36,7 @@ class MockModelTypeChangeProcessor : public ModelTypeChangeProcessor { ...@@ -36,6 +36,7 @@ class MockModelTypeChangeProcessor : public ModelTypeChangeProcessor {
const std::string& storage_key, const std::string& storage_key,
MetadataChangeList* metadata_change_list)); MetadataChangeList* metadata_change_list));
MOCK_METHOD1(UntrackEntity, void(const EntityData& entity_data)); MOCK_METHOD1(UntrackEntity, void(const EntityData& entity_data));
MOCK_METHOD1(OnModelStarting, void(ModelTypeSyncBridge* bridge));
// TODO(crbug.com/729950): Use unique_ptr here directly once move-only // TODO(crbug.com/729950): Use unique_ptr here directly once move-only
// arguments are supported in gMock. // arguments are supported in gMock.
MOCK_METHOD2(DoModelReadyToSync, MOCK_METHOD2(DoModelReadyToSync,
......
...@@ -60,6 +60,14 @@ class ModelTypeChangeProcessor { ...@@ -60,6 +60,14 @@ class ModelTypeChangeProcessor {
// change_processor()->Delete() instead. // change_processor()->Delete() instead.
virtual void UntrackEntity(const EntityData& entity_data) = 0; virtual void UntrackEntity(const EntityData& entity_data) = 0;
// Pass the pointer to the processor so that the processor can notify the
// bridge that sync is starting.
// This is a intermediate hack needed for fixing https://crbug.com/819993.
// TODO(jkrcal): Remove this hack (either by removing the bridge pointer from
// ModelReadyToSync or, preferrably, by swapping the ownership of the bridge
// and the processor).
virtual void OnModelStarting(ModelTypeSyncBridge* bridge) = 0;
// The |bridge| is expected to call this exactly once unless it encounters an // The |bridge| is expected to call this exactly once unless it encounters an
// error. Ideally ModelReadyToSync() is called as soon as possible during // error. Ideally ModelReadyToSync() is called as soon as possible during
// initialization, and must be called before invoking either Put() or // initialization, and must be called before invoking either Put() or
......
...@@ -15,6 +15,7 @@ ModelTypeSyncBridge::ModelTypeSyncBridge( ...@@ -15,6 +15,7 @@ ModelTypeSyncBridge::ModelTypeSyncBridge(
std::unique_ptr<ModelTypeChangeProcessor> change_processor) std::unique_ptr<ModelTypeChangeProcessor> change_processor)
: change_processor_(std::move(change_processor)) { : change_processor_(std::move(change_processor)) {
DCHECK(change_processor_); DCHECK(change_processor_);
change_processor_->OnModelStarting(this);
} }
ModelTypeSyncBridge::~ModelTypeSyncBridge() {} ModelTypeSyncBridge::~ModelTypeSyncBridge() {}
......
...@@ -81,14 +81,22 @@ void ClientTagBasedModelTypeProcessor::OnSyncStarting( ...@@ -81,14 +81,22 @@ void ClientTagBasedModelTypeProcessor::OnSyncStarting(
ConnectIfReady(); ConnectIfReady();
} }
void ClientTagBasedModelTypeProcessor::OnModelStarting(
ModelTypeSyncBridge* bridge) {
DCHECK(bridge);
bridge_ = bridge;
}
void ClientTagBasedModelTypeProcessor::ModelReadyToSync( void ClientTagBasedModelTypeProcessor::ModelReadyToSync(
ModelTypeSyncBridge* bridge, ModelTypeSyncBridge* bridge,
std::unique_ptr<MetadataBatch> batch) { std::unique_ptr<MetadataBatch> batch) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(entities_.empty()); DCHECK(entities_.empty());
DCHECK(bridge); DCHECK(!model_ready_to_sync_);
// The |bridge| argument is ignored here because it is already stored as
// |bridge_| by OnModelStarting().
bridge_ = bridge; model_ready_to_sync_ = true;
// The model already experienced an error; abort; // The model already experienced an error; abort;
if (model_error_) if (model_error_)
...@@ -119,7 +127,13 @@ void ClientTagBasedModelTypeProcessor::ModelReadyToSync( ...@@ -119,7 +127,13 @@ void ClientTagBasedModelTypeProcessor::ModelReadyToSync(
} }
bool ClientTagBasedModelTypeProcessor::IsModelReadyOrError() const { bool ClientTagBasedModelTypeProcessor::IsModelReadyOrError() const {
return model_error_ || bridge_; return model_error_ || model_ready_to_sync_;
}
bool ClientTagBasedModelTypeProcessor::IsAllowingChanges() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// Changes can be handled correctly even before pending data is loaded.
return model_ready_to_sync_;
} }
void ClientTagBasedModelTypeProcessor::ConnectIfReady() { void ClientTagBasedModelTypeProcessor::ConnectIfReady() {
...@@ -141,12 +155,6 @@ void ClientTagBasedModelTypeProcessor::ConnectIfReady() { ...@@ -141,12 +155,6 @@ void ClientTagBasedModelTypeProcessor::ConnectIfReady() {
start_callback_.Reset(); start_callback_.Reset();
} }
bool ClientTagBasedModelTypeProcessor::IsAllowingChanges() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// Changes can be handled correctly even before pending data is loaded.
return bridge_ != nullptr;
}
bool ClientTagBasedModelTypeProcessor::IsConnected() const { bool ClientTagBasedModelTypeProcessor::IsConnected() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return !!worker_; return !!worker_;
...@@ -155,7 +163,7 @@ bool ClientTagBasedModelTypeProcessor::IsConnected() const { ...@@ -155,7 +163,7 @@ bool ClientTagBasedModelTypeProcessor::IsConnected() const {
void ClientTagBasedModelTypeProcessor::DisableSync() { void ClientTagBasedModelTypeProcessor::DisableSync() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// Disabling sync for a type never happens before the model is ready to sync. // Disabling sync for a type never happens before the model is ready to sync.
DCHECK(bridge_); DCHECK(model_ready_to_sync_);
std::unique_ptr<MetadataChangeList> change_list = std::unique_ptr<MetadataChangeList> change_list =
bridge_->CreateMetadataChangeList(); bridge_->CreateMetadataChangeList();
...@@ -179,7 +187,7 @@ void ClientTagBasedModelTypeProcessor::DisableSync() { ...@@ -179,7 +187,7 @@ void ClientTagBasedModelTypeProcessor::DisableSync() {
case ModelTypeSyncBridge::DisableSyncResponse::kModelNoLongerReadyToSync: case ModelTypeSyncBridge::DisableSyncResponse::kModelNoLongerReadyToSync:
// Model not ready to sync, so wait until the bridge calls // Model not ready to sync, so wait until the bridge calls
// ModelReadyToSync(). // ModelReadyToSync().
bridge_ = nullptr; model_ready_to_sync_ = false;
break; break;
} }
} }
...@@ -990,10 +998,10 @@ void ClientTagBasedModelTypeProcessor::RemoveEntity( ...@@ -990,10 +998,10 @@ void ClientTagBasedModelTypeProcessor::RemoveEntity(
} }
void ClientTagBasedModelTypeProcessor::ResetState() { void ClientTagBasedModelTypeProcessor::ResetState() {
// This should reset all mutable fields (except for |bridge_| while is null // This should reset all mutable fields (except for |bridge_|).
// while the bridge is not ready to sync).
worker_.reset(); worker_.reset();
model_error_.reset(); model_error_.reset();
model_ready_to_sync_ = false;
entities_.clear(); entities_.clear();
storage_key_to_tag_hash_.clear(); storage_key_to_tag_hash_.clear();
model_type_state_ = sync_pb::ModelTypeState(); model_type_state_ = sync_pb::ModelTypeState();
......
...@@ -48,10 +48,6 @@ class ClientTagBasedModelTypeProcessor : public ModelTypeProcessor, ...@@ -48,10 +48,6 @@ class ClientTagBasedModelTypeProcessor : public ModelTypeProcessor,
bool commit_only); bool commit_only);
~ClientTagBasedModelTypeProcessor() override; ~ClientTagBasedModelTypeProcessor() override;
// Whether the processor is allowing changes to its model type. If this is
// false, the bridge should not allow any changes to its data.
bool IsAllowingChanges() const;
// Returns true if the handshake with sync thread is complete. // Returns true if the handshake with sync thread is complete.
bool IsConnected() const; bool IsConnected() const;
...@@ -65,6 +61,7 @@ class ClientTagBasedModelTypeProcessor : public ModelTypeProcessor, ...@@ -65,6 +61,7 @@ class ClientTagBasedModelTypeProcessor : public ModelTypeProcessor,
const std::string& storage_key, const std::string& storage_key,
MetadataChangeList* metadata_change_list) override; MetadataChangeList* metadata_change_list) override;
void UntrackEntity(const EntityData& entity_data) override; void UntrackEntity(const EntityData& entity_data) override;
void OnModelStarting(ModelTypeSyncBridge* bridge) override;
void ModelReadyToSync(ModelTypeSyncBridge* bridge, void ModelReadyToSync(ModelTypeSyncBridge* bridge,
std::unique_ptr<MetadataBatch> batch) override; std::unique_ptr<MetadataBatch> batch) override;
void OnSyncStarting(const ModelErrorHandler& error_handler, void OnSyncStarting(const ModelErrorHandler& error_handler,
...@@ -95,6 +92,10 @@ class ClientTagBasedModelTypeProcessor : public ModelTypeProcessor, ...@@ -95,6 +92,10 @@ class ClientTagBasedModelTypeProcessor : public ModelTypeProcessor,
// Returns true if the model is ready or encountered an error. // Returns true if the model is ready or encountered an error.
bool IsModelReadyOrError() const; bool IsModelReadyOrError() const;
// Whether the processor is allowing changes to its model type. If this is
// false, the bridge should not allow any changes to its data.
bool IsAllowingChanges() const;
// If preconditions are met, inform sync that we are ready to connect. // If preconditions are met, inform sync that we are ready to connect.
void ConnectIfReady(); void ConnectIfReady();
...@@ -225,6 +226,10 @@ class ClientTagBasedModelTypeProcessor : public ModelTypeProcessor, ...@@ -225,6 +226,10 @@ class ClientTagBasedModelTypeProcessor : public ModelTypeProcessor,
// and so it can be passed to sync if it happened prior to sync being ready. // and so it can be passed to sync if it happened prior to sync being ready.
base::Optional<ModelError> model_error_; base::Optional<ModelError> model_error_;
// Whether the model has initialized its internal state for sync (and provided
// metadata).
bool model_ready_to_sync_ = false;
//////////////// ////////////////
// Sync state // // Sync state //
//////////////// ////////////////
......
...@@ -184,6 +184,11 @@ class SessionSyncBridgeTest : public ::testing::Test { ...@@ -184,6 +184,11 @@ class SessionSyncBridgeTest : public ::testing::Test {
~SessionSyncBridgeTest() override {} ~SessionSyncBridgeTest() override {}
void InitializeBridge() { void InitializeBridge() {
real_processor_ =
std::make_unique<syncer::ClientTagBasedModelTypeProcessor>(
syncer::SESSIONS, /*dump_stack=*/base::DoNothing(),
/*commit_only=*/false);
mock_processor_.DelegateCallsByDefaultTo(real_processor_.get());
// Instantiate the bridge. // Instantiate the bridge.
bridge_ = std::make_unique<SessionSyncBridge>( bridge_ = std::make_unique<SessionSyncBridge>(
&mock_sync_sessions_client_, &mock_sync_prefs_, &mock_sync_sessions_client_, &mock_sync_prefs_,
...@@ -192,11 +197,6 @@ class SessionSyncBridgeTest : public ::testing::Test { ...@@ -192,11 +197,6 @@ class SessionSyncBridgeTest : public ::testing::Test {
syncer::ModelTypeStoreTestUtil::FactoryForForwardingStore(store_.get()), syncer::ModelTypeStoreTestUtil::FactoryForForwardingStore(store_.get()),
mock_foreign_sessions_updated_callback_.Get(), mock_foreign_sessions_updated_callback_.Get(),
mock_processor_.CreateForwardingProcessor()); mock_processor_.CreateForwardingProcessor());
real_processor_ =
std::make_unique<syncer::ClientTagBasedModelTypeProcessor>(
syncer::SESSIONS, /*dump_stack=*/base::DoNothing(),
/*commit_only=*/false);
mock_processor_.DelegateCallsByDefaultTo(real_processor_.get());
} }
void ShutdownBridge() { void ShutdownBridge() {
......
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