Fix thread update race for draft update.

This commit is contained in:
Clark 2023-05-30 10:44:52 -04:00 committed by GitHub
parent c503df5eec
commit 05edc715ef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1389,90 +1389,96 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
return false
}
val meaningfulMessages = messages.hasMeaningfulMessage(threadId)
writableDatabase.beginTransaction()
try {
val meaningfulMessages = messages.hasMeaningfulMessage(threadId)
val isPinned by lazy { getPinnedThreadIds().contains(threadId) }
val shouldDelete by lazy { allowDeletion && !isPinned && !messages.containsStories(threadId) }
val isPinned by lazy { getPinnedThreadIds().contains(threadId) }
val shouldDelete by lazy { allowDeletion && !isPinned && !messages.containsStories(threadId) }
if (!meaningfulMessages) {
if (shouldDelete) {
Log.d(TAG, "Deleting thread $threadId because it has no meaningful messages.")
deleteConversation(threadId)
return true
} else if (!isPinned) {
return false
}
}
val record: MessageRecord = try {
messages.getConversationSnippet(threadId)
} catch (e: NoSuchMessageException) {
val scheduledMessage: MessageRecord? = messages.getScheduledMessagesInThread(threadId).lastOrNull()
if (scheduledMessage == null) {
Log.w(TAG, "Failed to get a conversation snippet for thread $threadId")
if (!meaningfulMessages) {
if (shouldDelete) {
Log.d(TAG, "Deleting thread $threadId because it has no meaningful messages.")
deleteConversation(threadId)
writableDatabase.setTransactionSuccessful()
return true
} else if (!isPinned) {
return false
}
}
if (isPinned) {
updateThread(
threadId = threadId,
meaningfulMessages = meaningfulMessages,
body = null,
attachment = null,
contentType = null,
extra = null,
date = 0,
status = 0,
deliveryReceiptCount = 0,
type = 0,
unarchive = unarchive,
expiresIn = 0,
readReceiptCount = 0
)
val record: MessageRecord = try {
messages.getConversationSnippet(threadId)
} catch (e: NoSuchMessageException) {
val scheduledMessage: MessageRecord? = messages.getScheduledMessagesInThread(threadId).lastOrNull()
if (scheduledMessage == null) {
Log.w(TAG, "Failed to get a conversation snippet for thread $threadId")
if (shouldDelete) {
deleteConversation(threadId)
writableDatabase.setTransactionSuccessful()
} else if (isPinned) {
updateThread(
threadId = threadId,
meaningfulMessages = meaningfulMessages,
body = null,
attachment = null,
contentType = null,
extra = null,
date = 0,
status = 0,
deliveryReceiptCount = 0,
type = 0,
unarchive = unarchive,
expiresIn = 0,
readReceiptCount = 0
)
writableDatabase.setTransactionSuccessful()
}
return true
} else {
Log.i(TAG, "Using scheduled message for conversation snippet")
scheduledMessage
}
return true
} else {
Log.i(TAG, "Using scheduled message for conversation snippet")
scheduledMessage
}
}
val drafts: DraftTable.Drafts = SignalDatabase.drafts.getDrafts(threadId)
if (drafts.isNotEmpty()) {
val threadRecord: ThreadRecord? = getThreadRecord(threadId)
if (threadRecord != null &&
threadRecord.type == MessageTypes.BASE_DRAFT_TYPE &&
threadRecord.date > record.timestamp
) {
return false
val drafts: DraftTable.Drafts = SignalDatabase.drafts.getDrafts(threadId)
if (drafts.isNotEmpty()) {
val threadRecord: ThreadRecord? = getThreadRecord(threadId)
if (threadRecord != null &&
threadRecord.type == MessageTypes.BASE_DRAFT_TYPE &&
threadRecord.date > record.timestamp
) {
return false
}
}
val threadBody: ThreadBody = ThreadBodyUtil.getFormattedBodyFor(context, record)
updateThread(
threadId = threadId,
meaningfulMessages = meaningfulMessages,
body = threadBody.body.toString(),
attachment = getAttachmentUriFor(record),
contentType = getContentTypeFor(record),
extra = getExtrasFor(record, threadBody),
date = record.timestamp,
status = record.deliveryStatus,
deliveryReceiptCount = record.deliveryReceiptCount,
type = record.type,
unarchive = unarchive,
expiresIn = record.expiresIn,
readReceiptCount = record.readReceiptCount
)
if (notifyListeners) {
notifyConversationListListeners()
}
writableDatabase.setTransactionSuccessful()
return false
} finally {
writableDatabase.endTransaction()
}
val threadBody: ThreadBody = ThreadBodyUtil.getFormattedBodyFor(context, record)
updateThread(
threadId = threadId,
meaningfulMessages = meaningfulMessages,
body = threadBody.body.toString(),
attachment = getAttachmentUriFor(record),
contentType = getContentTypeFor(record),
extra = getExtrasFor(record, threadBody),
date = record.timestamp,
status = record.deliveryStatus,
deliveryReceiptCount = record.deliveryReceiptCount,
type = record.type,
unarchive = unarchive,
expiresIn = record.expiresIn,
readReceiptCount = record.readReceiptCount
)
if (notifyListeners) {
notifyConversationListListeners()
}
return false
}
fun updateSnippetTypeSilently(threadId: Long) {