Fix 'mutation during enumeration' and 'bad ordering' crashes.

This commit is contained in:
Matthew Chen 2019-01-16 22:38:22 -05:00
parent fc36fe4fcf
commit debf2e7a95

View file

@ -49,8 +49,13 @@ public class OWS110SortIdMigration: OWSDatabaseMigration {
let totalCount: UInt = legacySorting.numberOfItemsInAllGroups()
var completedCount: UInt = 0
var seenGroups: Set<String> = Set()
var allGroups = [String]()
legacySorting.enumerateGroups { group, _ in
allGroups.append(group)
}
var seenGroups: Set<String> = Set()
for group in allGroups {
autoreleasepool {
// Sanity Check #1
// Make sure our enumeration is monotonically increasing.
@ -69,24 +74,30 @@ public class OWS110SortIdMigration: OWSDatabaseMigration {
}
seenGroups.insert(group)
legacySorting.enumerateKeysAndObjects(inGroup: group) { (_, _, object, _, _) in
var groupKeys = [String]()
legacySorting.enumerateKeys(inGroup: group, using: { (_, key, _, _) in
groupKeys.append(key)
})
let groupKeyBatchSize: Int = 1024
for batch in groupKeys.chunked(by: groupKeyBatchSize) {
autoreleasepool {
guard let interaction = object as? TSInteraction else {
owsFailDebug("unexpected object: \(type(of: object))")
return
}
for uniqueId in batch {
guard let interaction = TSInteraction.fetch(uniqueId: uniqueId, transaction: transaction) else {
owsFailDebug("Could not load interaction: \(uniqueId)")
return
}
if interaction.timestampForLegacySorting() < previousTimestampForLegacySorting {
owsFailDebug("unexpected object ordering previousTimestampForLegacySorting: \(previousTimestampForLegacySorting) interaction.timestampForLegacySorting: \(interaction.timestampForLegacySorting())")
}
previousTimestampForLegacySorting = interaction.timestampForLegacySorting()
guard interaction.timestampForLegacySorting() >= previousTimestampForLegacySorting else {
owsFail("unexpected object ordering previousTimestampForLegacySorting: \(previousTimestampForLegacySorting) interaction.timestampForLegacySorting: \(interaction.timestampForLegacySorting)")
}
previousTimestampForLegacySorting = interaction.timestampForLegacySorting()
interaction.saveNextSortId(transaction: transaction)
interaction.saveNextSortId(transaction: transaction)
completedCount += 1
if completedCount % 100 == 0 {
// Legit usage of legacy sorting for migration to new sorting
Logger.info("thread: \(interaction.uniqueThreadId), timestampForLegacySorting:\(interaction.timestampForLegacySorting()), sortId: \(interaction.sortId) totalCount: \(totalCount), completedcount: \(completedCount)")
completedCount += 1
if completedCount % 100 == 0 {
// Legit usage of legacy sorting for migration to new sorting
Logger.info("thread: \(interaction.uniqueThreadId), timestampForLegacySorting:\(interaction.timestampForLegacySorting()), sortId: \(interaction.sortId) totalCount: \(totalCount), completedcount: \(completedCount)")
}
}
}
}