Improve receipt processing via faster thread updates.
This commit is contained in:
parent
b0733dcd51
commit
a81e5c4e6b
2 changed files with 71 additions and 9 deletions
|
@ -1678,17 +1678,39 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
|||
.run()
|
||||
}
|
||||
|
||||
fun getIncomingMeaningfulMessageCountSince(threadId: Long, afterTime: Long): Int {
|
||||
val meaningfulMessagesQuery = buildMeaningfulMessagesQuery(threadId)
|
||||
val where = "${meaningfulMessagesQuery.where} AND $DATE_RECEIVED >= ? AND NOT ($outgoingTypeClause)"
|
||||
val whereArgs = appendArg(meaningfulMessagesQuery.whereArgs, afterTime.toString())
|
||||
/**
|
||||
* Returns the receipt status of the most recent meaningful message in the thread if it matches the provided message ID.
|
||||
* If the ID doesn't match or otherwise can't be found, it will return null.
|
||||
*
|
||||
* This is a very specific method for use with [ThreadTable.updateReceiptStatus] to improve the perfomance of
|
||||
* processing receipts.
|
||||
*/
|
||||
fun getReceiptStatusIfItsTheMostRecentMeaningfulMessage(messageId: Long, threadId: Long): MessageReceiptStatus? {
|
||||
val query = buildMeaningfulMessagesQuery(threadId)
|
||||
|
||||
return readableDatabase
|
||||
.select("COUNT(*)")
|
||||
.select(ID, DELIVERY_RECEIPT_COUNT, READ_RECEIPT_COUNT, VIEWED_RECEIPT_COUNT, TYPE)
|
||||
.from(TABLE_NAME)
|
||||
.where(where, whereArgs)
|
||||
.where(query.where, query.whereArgs)
|
||||
.orderBy("$DATE_RECEIVED DESC")
|
||||
.limit(1)
|
||||
.run()
|
||||
.readToSingleInt()
|
||||
.use { cursor ->
|
||||
if (cursor.moveToFirst()) {
|
||||
if (cursor.requireLong(ID) != messageId) {
|
||||
return null
|
||||
}
|
||||
|
||||
return MessageReceiptStatus(
|
||||
deliveryCount = cursor.requireInt(DELIVERY_RECEIPT_COUNT),
|
||||
readCount = cursor.requireInt(READ_RECEIPT_COUNT),
|
||||
viewedCount = cursor.requireInt(VIEWED_RECEIPT_COUNT),
|
||||
type = cursor.requireLong(TYPE)
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildMeaningfulMessagesQuery(threadId: Long): SqlUtil.Query {
|
||||
|
@ -4129,7 +4151,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
|||
messageUpdates = incrementReceiptCountInternal(targetTimestamp, receiptAuthor, receiptSentTimestamp, receiptType, messageQualifier)
|
||||
|
||||
for (messageUpdate in messageUpdates) {
|
||||
threads.update(messageUpdate.threadId, false)
|
||||
threads.updateReceiptStatus(messageUpdate.messageId.id, messageUpdate.threadId)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4161,7 +4183,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
|||
|
||||
for (update in messageUpdates) {
|
||||
if (update.shouldUpdateSnippet) {
|
||||
threads.updateSilently(update.threadId, false)
|
||||
threads.updateReceiptStatus(update.messageId.id, update.threadId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4722,6 +4744,17 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
|||
VIEWED(VIEWED_RECEIPT_COUNT, GroupReceiptTable.STATUS_VIEWED)
|
||||
}
|
||||
|
||||
data class MessageReceiptStatus(
|
||||
val readCount: Int,
|
||||
val deliveryCount: Int,
|
||||
val viewedCount: Int,
|
||||
val type: Long
|
||||
)
|
||||
|
||||
enum class MessageStatus {
|
||||
PENDING, SENT, DELIVERED, READ, VIEWED, FAILED
|
||||
}
|
||||
|
||||
data class SyncMessageId(
|
||||
val recipientId: RecipientId,
|
||||
val timetamp: Long
|
||||
|
|
|
@ -1402,6 +1402,35 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
|||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the thread with the receipt status of the message provided, but only if that message is the most recent meaningful message.
|
||||
* The idea here is that if it _is_ the most meaningful message, we can set the new status. If it's not, there's no need to update
|
||||
* the thread at all.
|
||||
*/
|
||||
fun updateReceiptStatus(messageId: Long, threadId: Long) {
|
||||
val status = messages.getReceiptStatusIfItsTheMostRecentMeaningfulMessage(messageId, threadId)
|
||||
|
||||
if (status != null) {
|
||||
Log.d(TAG, "Updating receipt status for thread $threadId")
|
||||
writableDatabase
|
||||
.update(TABLE_NAME)
|
||||
.values(
|
||||
DELIVERY_RECEIPT_COUNT to status.deliveryCount,
|
||||
READ_RECEIPT_COUNT to status.readCount,
|
||||
STATUS to when {
|
||||
MessageTypes.isFailedMessageType(status.type) -> MessageTable.Status.STATUS_FAILED
|
||||
MessageTypes.isSentType(status.type) -> MessageTable.Status.STATUS_COMPLETE
|
||||
MessageTypes.isPendingMessageType(status.type) -> MessageTable.Status.STATUS_PENDING
|
||||
else -> MessageTable.Status.STATUS_NONE
|
||||
}
|
||||
)
|
||||
.where("$ID = ?", threadId)
|
||||
.run()
|
||||
} else {
|
||||
Log.d(TAG, "Receipt was for an old message, not updating thread.")
|
||||
}
|
||||
}
|
||||
|
||||
private fun update(threadId: Long, unarchive: Boolean, allowDeletion: Boolean, notifyListeners: Boolean): Boolean {
|
||||
if (threadId == -1L) {
|
||||
Log.d(TAG, "Skipping update for threadId -1")
|
||||
|
|
Loading…
Add table
Reference in a new issue