1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "sync/internal_api/sync_rollback_manager.h"
7 #include "sync/internal_api/public/base/model_type.h"
8 #include "sync/internal_api/public/read_node.h"
9 #include "sync/internal_api/public/read_transaction.h"
10 #include "sync/internal_api/public/util/syncer_error.h"
11 #include "sync/internal_api/public/write_transaction.h"
12 #include "sync/syncable/directory.h"
13 #include "sync/syncable/mutable_entry.h"
18 SyncRollbackManager::SyncRollbackManager()
19 : change_delegate_(NULL
) {
22 SyncRollbackManager::~SyncRollbackManager() {
25 void SyncRollbackManager::Init(InitArgs
* args
) {
26 if (SyncRollbackManagerBase::InitInternal(
27 args
->database_location
,
28 args
->internal_components_factory
.get(),
29 InternalComponentsFactory::STORAGE_ON_DISK
,
30 args
->unrecoverable_error_handler
,
31 args
->report_unrecoverable_error_function
)) {
32 change_delegate_
= args
->change_delegate
;
34 for (size_t i
= 0; i
< args
->workers
.size(); ++i
) {
35 ModelSafeGroup group
= args
->workers
[i
]->GetModelSafeGroup();
36 CHECK(workers_
.find(group
) == workers_
.end());
37 workers_
[group
] = args
->workers
[i
];
40 rollback_ready_types_
= GetUserShare()->directory
->InitialSyncEndedTypes();
41 rollback_ready_types_
.RetainAll(BackupTypes());
45 void SyncRollbackManager::StartSyncingNormally(
46 const ModelSafeRoutingInfo
& routing_info
, base::Time last_poll_time
){
47 if (rollback_ready_types_
.Empty()) {
52 std::map
<ModelType
, syncable::Directory::Metahandles
> to_delete
;
54 WriteTransaction
trans(FROM_HERE
, GetUserShare());
55 syncable::Directory::Metahandles unsynced
;
56 GetUserShare()->directory
->GetUnsyncedMetaHandles(trans
.GetWrappedTrans(),
58 for (size_t i
= 0; i
< unsynced
.size(); ++i
) {
59 syncable::MutableEntry
e(trans
.GetWrappedWriteTrans(),
60 syncable::GET_BY_HANDLE
, unsynced
[i
]);
61 if (!e
.good() || e
.GetIsDel() || e
.GetId().ServerKnows())
64 // TODO(haitaol): roll back entries that are backed up but whose content
65 // is merged with local model during association.
67 ModelType type
= GetModelTypeFromSpecifics(e
.GetSpecifics());
68 if (!rollback_ready_types_
.Has(type
))
71 to_delete
[type
].push_back(unsynced
[i
]);
75 for (std::map
<ModelType
, syncable::Directory::Metahandles
>::iterator it
=
76 to_delete
.begin(); it
!= to_delete
.end(); ++it
) {
77 ModelSafeGroup group
= routing_info
.find(it
->first
)->second
;
78 CHECK(workers_
.find(group
) != workers_
.end());
79 workers_
[group
]->DoWorkAndWaitUntilDone(
80 base::Bind(&SyncRollbackManager::DeleteOnWorkerThread
,
81 base::Unretained(this),
82 it
->first
, it
->second
));
88 SyncerError
SyncRollbackManager::DeleteOnWorkerThread(
89 ModelType type
, std::vector
<int64
> handles
) {
90 CHECK(change_delegate_
);
93 ChangeRecordList deletes
;
94 WriteTransaction
trans(FROM_HERE
, GetUserShare());
95 for (size_t i
= 0; i
< handles
.size(); ++i
) {
96 syncable::MutableEntry
e(trans
.GetWrappedWriteTrans(),
97 syncable::GET_BY_HANDLE
, handles
[i
]);
98 if (!e
.good() || e
.GetIsDel())
102 del
.action
= ChangeRecord::ACTION_DELETE
;
104 del
.specifics
= e
.GetSpecifics();
105 deletes
.push_back(del
);
108 change_delegate_
->OnChangesApplied(type
, 1, &trans
,
109 MakeImmutable(&deletes
));
112 change_delegate_
->OnChangesComplete(type
);
116 void SyncRollbackManager::NotifyRollbackDone() {
117 SyncProtocolError error
;
118 error
.action
= ROLLBACK_DONE
;
119 FOR_EACH_OBSERVER(SyncManager::Observer
, *GetObservers(),
120 OnActionableError(error
));
123 } // namespace syncer