Commit 8e46ab37 authored by Marc Treib's avatar Marc Treib Committed by Commit Bot

ProfileSyncService: shut down immediately on unrecoverable errors

Previously, we'd post a task to perform the shutdown. This meant that
there was a brief period where the unrecoverable error was already set,
but Sync was still active, which made things hard to reason about.
This CL removes the task-posting and instead just directly calls
OnUnrecoverableErrorImpl (which calls ShutdownImpl), which doesn't seem
to have any ill effects.

Bug: 839834
Change-Id: I998488332c531e817ffcd19e44df0e1273d091a5
Reviewed-on: https://chromium-review.googlesource.com/1163707
Commit-Queue: Marc Treib <treib@chromium.org>
Reviewed-by: default avatarMikel Astiz <mastiz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#581196}
parent 1c472ffd
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "components/browser_sync/browser_sync_switches.h" #include "components/browser_sync/browser_sync_switches.h"
#include "components/browser_sync/sync_auth_manager.h" #include "components/browser_sync/sync_auth_manager.h"
#include "components/invalidation/impl/invalidation_prefs.h" #include "components/invalidation/impl/invalidation_prefs.h"
...@@ -53,7 +52,6 @@ ...@@ -53,7 +52,6 @@
#include "components/sync/engine/polling_constants.h" #include "components/sync/engine/polling_constants.h"
#include "components/sync/engine/sync_encryption_handler.h" #include "components/sync/engine/sync_encryption_handler.h"
#include "components/sync/engine/sync_string_conversions.h" #include "components/sync/engine/sync_string_conversions.h"
#include "components/sync/js/js_event_details.h"
#include "components/sync/model/change_processor.h" #include "components/sync/model/change_processor.h"
#include "components/sync/model/model_type_change_processor.h" #include "components/sync/model/model_type_change_processor.h"
#include "components/sync/model/model_type_store_service.h" #include "components/sync/model/model_type_store_service.h"
...@@ -791,14 +789,8 @@ syncer::SyncService::TransportState ProfileSyncService::GetTransportState() ...@@ -791,14 +789,8 @@ syncer::SyncService::TransportState ProfileSyncService::GetTransportState()
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!IsEngineAllowedToStart()) { if (!IsEngineAllowedToStart()) {
// We shouldn't have an engine while in a disabled state, with one // We shouldn't have an engine while in a disabled state.
// exception: When encountering an unrecoverable error, we post a task to DCHECK(!engine_);
// shut down instead of doing it immediately, so there's a brief timeframe
// where we have an unrecoverable error but the engine still exists.
// TODO(crbug.com/839834): See if we can change this by either shutting down
// immediately (not posting a task), or setting the unrecoverable error as
// part of the posted task.
DCHECK(HasDisableReason(DISABLE_REASON_UNRECOVERABLE_ERROR) || !engine_);
return TransportState::DISABLED; return TransportState::DISABLED;
} }
...@@ -913,17 +905,21 @@ void ProfileSyncService::ClearUnrecoverableError() { ...@@ -913,17 +905,21 @@ void ProfileSyncService::ClearUnrecoverableError() {
// to do as little work as possible, to avoid further corruption or crashes. // to do as little work as possible, to avoid further corruption or crashes.
void ProfileSyncService::OnUnrecoverableError(const base::Location& from_here, void ProfileSyncService::OnUnrecoverableError(const base::Location& from_here,
const std::string& message) { const std::string& message) {
// TODO(crbug.com/840720): Get rid of the UnrecoverableErrorHandler interface
// and instead pass a callback.
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// Unrecoverable errors that arrive via the syncer::UnrecoverableErrorHandler // Unrecoverable errors that arrive via the syncer::UnrecoverableErrorHandler
// interface are assumed to originate within the syncer. // interface are assumed to originate within the syncer.
unrecoverable_error_reason_ = ERROR_REASON_SYNCER; OnUnrecoverableErrorImpl(from_here, message, ERROR_REASON_SYNCER);
OnUnrecoverableErrorImpl(from_here, message);
} }
void ProfileSyncService::OnUnrecoverableErrorImpl( void ProfileSyncService::OnUnrecoverableErrorImpl(
const base::Location& from_here, const base::Location& from_here,
const std::string& message) { const std::string& message,
DCHECK_NE(unrecoverable_error_reason_, ERROR_REASON_UNSET); UnrecoverableErrorReason reason) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK_NE(reason, ERROR_REASON_UNSET);
unrecoverable_error_reason_ = reason;
unrecoverable_error_message_ = message; unrecoverable_error_message_ = message;
unrecoverable_error_location_ = from_here; unrecoverable_error_location_ = from_here;
...@@ -932,13 +928,8 @@ void ProfileSyncService::OnUnrecoverableErrorImpl( ...@@ -932,13 +928,8 @@ void ProfileSyncService::OnUnrecoverableErrorImpl(
LOG(ERROR) << "Unrecoverable error detected at " << from_here.ToString() LOG(ERROR) << "Unrecoverable error detected at " << from_here.ToString()
<< " -- ProfileSyncService unusable: " << message; << " -- ProfileSyncService unusable: " << message;
NotifyObservers();
// Shut all data types down. // Shut all data types down.
base::SequencedTaskRunnerHandle::Get()->PostTask( ShutdownImpl(syncer::DISABLE_SYNC);
FROM_HERE, base::BindOnce(&ProfileSyncService::ShutdownImpl,
sync_enabled_weak_factory_.GetWeakPtr(),
syncer::DISABLE_SYNC));
} }
void ProfileSyncService::ReenableDatatype(syncer::ModelType type) { void ProfileSyncService::ReenableDatatype(syncer::ModelType type) {
...@@ -984,8 +975,8 @@ void ProfileSyncService::OnEngineInitialized( ...@@ -984,8 +975,8 @@ void ProfileSyncService::OnEngineInitialized(
if (!success) { if (!success) {
// Something went unexpectedly wrong. Play it safe: stop syncing at once // Something went unexpectedly wrong. Play it safe: stop syncing at once
// and surface error UI to alert the user sync has stopped. // and surface error UI to alert the user sync has stopped.
OnInternalUnrecoverableError(FROM_HERE, "BackendInitialize failure", OnUnrecoverableErrorImpl(FROM_HERE, "BackendInitialize failure",
ERROR_REASON_ENGINE_INIT_FAILURE); ERROR_REASON_ENGINE_INIT_FAILURE);
return; return;
} }
...@@ -1121,9 +1112,9 @@ void ProfileSyncService::OnActionableError( ...@@ -1121,9 +1112,9 @@ void ProfileSyncService::OnActionableError(
expect_sync_configuration_aborted_ = true; expect_sync_configuration_aborted_ = true;
} }
// Trigger an unrecoverable error to stop syncing. // Trigger an unrecoverable error to stop syncing.
OnInternalUnrecoverableError(FROM_HERE, OnUnrecoverableErrorImpl(FROM_HERE,
last_actionable_error_.error_description, last_actionable_error_.error_description,
ERROR_REASON_ACTIONABLE_ERROR); ERROR_REASON_ACTIONABLE_ERROR);
break; break;
case syncer::DISABLE_SYNC_ON_CLIENT: case syncer::DISABLE_SYNC_ON_CLIENT:
if (error.error_type == syncer::NOT_MY_BIRTHDAY) { if (error.error_type == syncer::NOT_MY_BIRTHDAY) {
...@@ -1255,8 +1246,8 @@ void ProfileSyncService::OnConfigureDone( ...@@ -1255,8 +1246,8 @@ void ProfileSyncService::OnConfigureDone(
result.data_type_status_table.GetUnrecoverableErrorTypes()) + result.data_type_status_table.GetUnrecoverableErrorTypes()) +
": " + error.message(); ": " + error.message();
LOG(ERROR) << "ProfileSyncService error: " << message; LOG(ERROR) << "ProfileSyncService error: " << message;
OnInternalUnrecoverableError(error.location(), message, OnUnrecoverableErrorImpl(error.location(), message,
ERROR_REASON_CONFIGURATION_FAILURE); ERROR_REASON_CONFIGURATION_FAILURE);
return; return;
} }
...@@ -2078,15 +2069,6 @@ syncer::ModelTypeSet ProfileSyncService::GetDataTypesFromPreferenceProviders() ...@@ -2078,15 +2069,6 @@ syncer::ModelTypeSet ProfileSyncService::GetDataTypesFromPreferenceProviders()
return types; return types;
} }
void ProfileSyncService::OnInternalUnrecoverableError(
const base::Location& from_here,
const std::string& message,
UnrecoverableErrorReason reason) {
DCHECK_EQ(unrecoverable_error_reason_, ERROR_REASON_UNSET);
unrecoverable_error_reason_ = reason;
OnUnrecoverableErrorImpl(from_here, message);
}
bool ProfileSyncService::IsRetryingAccessTokenFetchForTest() const { bool ProfileSyncService::IsRetryingAccessTokenFetchForTest() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return auth_manager_->IsRetryingAccessTokenFetchForTest(); return auth_manager_->IsRetryingAccessTokenFetchForTest();
......
...@@ -526,9 +526,10 @@ class ProfileSyncService : public syncer::SyncService, ...@@ -526,9 +526,10 @@ class ProfileSyncService : public syncer::SyncService,
// Helper method for managing encryption UI. // Helper method for managing encryption UI.
bool IsEncryptedDatatypeEnabled() const; bool IsEncryptedDatatypeEnabled() const;
// Helper for OnUnrecoverableError and OnInternalUnrecoverableError. // Helper for OnUnrecoverableError.
void OnUnrecoverableErrorImpl(const base::Location& from_here, void OnUnrecoverableErrorImpl(const base::Location& from_here,
const std::string& message); const std::string& message,
UnrecoverableErrorReason reason);
// Stops the sync engine. Does NOT set IsSyncRequested to false. Use // Stops the sync engine. Does NOT set IsSyncRequested to false. Use
// RequestStop for that. |data_fate| controls whether the local sync data is // RequestStop for that. |data_fate| controls whether the local sync data is
...@@ -566,12 +567,6 @@ class ProfileSyncService : public syncer::SyncService, ...@@ -566,12 +567,6 @@ class ProfileSyncService : public syncer::SyncService,
bool sync_everything, bool sync_everything,
const syncer::ModelTypeSet chosen_types) const; const syncer::ModelTypeSet chosen_types) const;
// Internal unrecoverable error handler. Used to track error reason via
// Sync.UnrecoverableErrors histogram.
void OnInternalUnrecoverableError(const base::Location& from_here,
const std::string& message,
UnrecoverableErrorReason reason);
// Update UMA for syncing engine. // Update UMA for syncing engine.
void UpdateEngineInitUMA(bool success) const; void UpdateEngineInitUMA(bool success) const;
......
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