@@ -162,7 +162,36 @@ extension Snapshot {
162
162
163
163
let fileManager = FileManager ( )
164
164
165
- /// Start by deleting and pruning roots as needed.
165
+ /// Start by deleting and pruning roots as needed. We attempt to do this twice, as older versions of the persistence (prior to 0.4) didn't record the datastore ID along with the root id, which would therefor require extra work.
166
+ /// First, delete the root entries we know to be removed.
167
+ for datastoreRoot in datastoreRootsToPruneAndDelete {
168
+ guard let datastoreID = datastoreRoot. datastoreID else { continue }
169
+ let datastore = datastores [ datastoreID] ?? DiskPersistence < AccessMode > . Datastore ( id: datastoreID, snapshot: self )
170
+ do {
171
+ try await datastore. pruneRootObject ( with: datastoreRoot. datastoreRootID, mode: mode, shouldDelete: true )
172
+ } catch URLError . fileDoesNotExist , CocoaError. fileReadNoSuchFile , CocoaError. fileNoSuchFile , POSIXError. ENOENT {
173
+ /// This datastore root is already gone.
174
+ } catch {
175
+ print ( " Could not delete datastore root \( datastoreRoot) : \( error) " )
176
+ throw error
177
+ }
178
+ datastoreRootsToPruneAndDelete. remove ( datastoreRoot)
179
+ }
180
+ /// Prune the root entries that were just added, as they themselves refer to other deleted assets.
181
+ for datastoreRoot in datastoreRootsToPrune {
182
+ guard let datastoreID = datastoreRoot. datastoreID else { continue }
183
+ let datastore = datastores [ datastoreID] ?? DiskPersistence < AccessMode > . Datastore ( id: datastoreID, snapshot: self )
184
+ do {
185
+ try await datastore. pruneRootObject ( with: datastoreRoot. datastoreRootID, mode: mode, shouldDelete: false )
186
+ } catch URLError . fileDoesNotExist , CocoaError. fileReadNoSuchFile , CocoaError. fileNoSuchFile , POSIXError. ENOENT {
187
+ /// This datastore root is already gone.
188
+ } catch {
189
+ print ( " Could not prune datastore root \( datastoreRoot) : \( error) " )
190
+ throw error
191
+ }
192
+ datastoreRootsToPrune. remove ( datastoreRoot)
193
+ }
194
+ /// If any regerences remain, funnel into this code path for very old persistences.
166
195
if !datastoreRootsToPruneAndDelete. isEmpty || !datastoreRootsToPrune. isEmpty {
167
196
for (_, datastoreInfo) in iteration. dataStores {
168
197
/// Skip any roots for datastores being deleted, since we'll just unlink the whole directory in that case.
@@ -174,21 +203,23 @@ extension Snapshot {
174
203
for datastoreRoot in datastoreRootsToPruneAndDelete {
175
204
// TODO: Clean this up by also storing the datastore ID in with the root ID…
176
205
do {
177
- try await datastore. pruneRootObject ( with: datastoreRoot, mode: mode, shouldDelete: true )
206
+ try await datastore. pruneRootObject ( with: datastoreRoot. datastoreRootID , mode: mode, shouldDelete: true )
178
207
datastoreRootsToPruneAndDelete. remove ( datastoreRoot)
179
208
} catch {
180
209
/// This datastore did not contain the specified root, skip it for now.
210
+ print ( " Could not delete datastore root \( datastoreRoot) : \( error) . Will probably try again. " )
181
211
}
182
212
}
183
213
184
214
/// Prune the root entries that were just added, as they themselves refer to other deleted assets.
185
215
for datastoreRoot in datastoreRootsToPrune {
186
216
// TODO: Clean this up by also storing the datastore ID in with the root ID…
187
217
do {
188
- try await datastore. pruneRootObject ( with: datastoreRoot, mode: mode, shouldDelete: false )
218
+ try await datastore. pruneRootObject ( with: datastoreRoot. datastoreRootID , mode: mode, shouldDelete: false )
189
219
datastoreRootsToPrune. remove ( datastoreRoot)
190
220
} catch {
191
221
/// This datastore did not contain the specified root, skip it for now.
222
+ print ( " Could not prune datastore root \( datastoreRoot) : \( error) . Will probably try again. " )
192
223
}
193
224
}
194
225
}
0 commit comments