Fix backup perf issue by doing cleanup inline.

This commit is contained in:
Greyson Parrelli 2024-12-04 15:51:33 -05:00
parent e47861796e
commit 6d415ca85a
2 changed files with 52 additions and 33 deletions

View file

@ -13,7 +13,6 @@ import org.thoughtcrime.securesms.backup.v2.exporters.ChatItemArchiveExporter
import org.thoughtcrime.securesms.backup.v2.importer.ChatItemArchiveImporter
import org.thoughtcrime.securesms.database.GroupTable
import org.thoughtcrime.securesms.database.MessageTable
import org.thoughtcrime.securesms.database.MessageTypes
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.recipients.RecipientId
@ -68,6 +67,7 @@ fun MessageTable.getMessagesForBackup(db: SignalDatabase, backupTime: Long, medi
// Unfortunately we have some bad legacy data where the from_recipient_id is a group.
// This cleans it up. Reminder, this is only a snapshot of the data.
val cleanupStartTime = System.currentTimeMillis()
db.rawWritableDatabase.execSQL(
"""
UPDATE ${MessageTable.TABLE_NAME}
@ -78,16 +78,7 @@ fun MessageTable.getMessagesForBackup(db: SignalDatabase, backupTime: Long, medi
)
"""
)
// If someone re-registers with a new phone number, previous outgoing messages will no longer be associated with self.
// This cleans it up by changing the from to be the current self id for all outgoing messages.
db.rawWritableDatabase.execSQL(
"""
UPDATE ${MessageTable.TABLE_NAME}
SET ${MessageTable.FROM_RECIPIENT_ID} = ${selfRecipientId.toLong()}
WHERE (${MessageTable.TYPE} & ${MessageTypes.BASE_TYPE_MASK}) IN (${MessageTypes.OUTGOING_MESSAGE_TYPES.joinToString(",")})
"""
)
Log.d(TAG, "Cleanup took ${System.currentTimeMillis() - cleanupStartTime} ms")
return ChatItemArchiveExporter(
db = db,

View file

@ -390,36 +390,60 @@ private fun simpleUpdate(type: SimpleChatUpdate.Type): ChatUpdateMessage {
private fun BackupMessageRecord.toBasicChatItemBuilder(selfRecipientId: RecipientId, isGroupThread: Boolean, groupReceipts: List<GroupReceiptTable.GroupReceiptInfo>?, exportState: ExportState, backupStartTime: Long): ChatItem.Builder? {
val record = this
val direction = when {
record.type.isDirectionlessType() || record.messageExtras?.gv2UpdateDescription != null -> {
Direction.DIRECTIONLESS
}
MessageTypes.isOutgoingMessageType(record.type) || record.fromRecipientId == selfRecipientId.toLong() -> {
Direction.OUTGOING
}
else -> {
Direction.INCOMING
}
}
// If a user restores a backup with a different number, then they'll have outgoing messages from a non-self contact.
// We want to ensure all outgoing messages are from ourselves.
val fromRecipientId = if (direction == Direction.OUTGOING) {
selfRecipientId.toLong()
} else {
record.fromRecipientId
}
val builder = ChatItem.Builder().apply {
chatId = record.threadId
authorId = record.fromRecipientId
authorId = fromRecipientId
dateSent = record.dateSent
expireStartDate = record.expireStarted.takeIf { it > 0 }
expiresInMs = record.expiresIn.takeIf { it > 0 }
revisions = emptyList()
sms = record.type.isSmsType()
if (record.type.isDirectionlessType() || record.messageExtras?.gv2UpdateDescription != null) {
directionless = ChatItem.DirectionlessMessageDetails()
} else if (MessageTypes.isOutgoingMessageType(record.type) || record.fromRecipientId == selfRecipientId.toLong()) {
outgoing = ChatItem.OutgoingMessageDetails(
sendStatus = record.toRemoteSendStatus(isGroupThread, groupReceipts, exportState)
)
if (expiresInMs != null && outgoing?.sendStatus?.all { it.pending == null && it.failed == null } == true) {
Log.w(TAG, "Outgoing expiring message was sent but the timer wasn't started! Fixing.")
expireStartDate = record.dateReceived
when (direction) {
Direction.DIRECTIONLESS -> {
directionless = ChatItem.DirectionlessMessageDetails()
}
} else {
incoming = ChatItem.IncomingMessageDetails(
dateServerSent = record.dateServer.takeIf { it > 0 },
dateReceived = record.dateReceived,
read = record.read,
sealedSender = record.sealedSender
)
Direction.OUTGOING -> {
outgoing = ChatItem.OutgoingMessageDetails(
sendStatus = record.toRemoteSendStatus(isGroupThread, groupReceipts, exportState)
)
if (expiresInMs != null && incoming?.read == true && expireStartDate == null) {
Log.w(TAG, "Incoming expiring message was read but the timer wasn't started! Fixing.")
expireStartDate = record.dateReceived
if (expiresInMs != null && outgoing?.sendStatus?.all { it.pending == null && it.failed == null } == true) {
Log.w(TAG, "Outgoing expiring message was sent but the timer wasn't started! Fixing.")
expireStartDate = record.dateReceived
}
}
Direction.INCOMING -> {
incoming = ChatItem.IncomingMessageDetails(
dateServerSent = record.dateServer.takeIf { it > 0 },
dateReceived = record.dateReceived,
read = record.read,
sealedSender = record.sealedSender
)
if (expiresInMs != null && incoming?.read == true && expireStartDate == null) {
Log.w(TAG, "Incoming expiring message was read but the timer wasn't started! Fixing.")
expireStartDate = record.dateReceived
}
}
}
}
@ -1285,10 +1309,14 @@ private class BackupMessageRecord(
val viewOnce: Boolean
)
data class ExtraMessageData(
private data class ExtraMessageData(
val mentionsById: Map<Long, List<Mention>>,
val reactionsById: Map<Long, List<ReactionRecord>>,
val attachmentsById: Map<Long, List<DatabaseAttachment>>,
val groupReceiptsById: Map<Long, List<GroupReceiptTable.GroupReceiptInfo>>,
val isGroupThreadById: Map<Long, Boolean>
)
private enum class Direction {
OUTGOING, INCOMING, DIRECTIONLESS
}