fix an issue that a disappearing messages control message will be removed by a race condition

pull/731/head
Ryan ZHAO 4 months ago
parent b4f01db37e
commit bd0a25bbe9

@ -474,20 +474,18 @@ class ThreadDisappearingMessagesSettingsViewModel: SessionTableViewModel, Naviga
guard self.config != updatedConfig else { return } guard self.config != updatedConfig else { return }
dependencies.storage.writeAsync(using: dependencies) { [threadId, threadVariant, dependencies] db in dependencies.storage.writeAsync(using: dependencies) { [threadId, threadVariant, dependencies] db in
_ = try updatedConfig.saved(db)
let userPublicKey: String = getUserHexEncodedPublicKey(db, using: dependencies) let userPublicKey: String = getUserHexEncodedPublicKey(db, using: dependencies)
let currentTimestampMs: Int64 = SnodeAPI.currentOffsetTimestampMs() let currentTimestampMs: Int64 = SnodeAPI.currentOffsetTimestampMs()
let interactionId = try DisappearingMessagesConfiguration.insertControlMessage( let interactionId = try updatedConfig
.saved(db)
.insertControlMessage(
db, db,
threadId: threadId,
threadVariant: threadVariant, threadVariant: threadVariant,
authorId: userPublicKey, authorId: userPublicKey,
timestampMs: currentTimestampMs, timestampMs: currentTimestampMs,
serverHash: nil, serverHash: nil,
serverExpirationTimestamp: nil, serverExpirationTimestamp: nil
updatedConfiguration: updatedConfig
) )
let duration: UInt32? = { let duration: UInt32? = {

@ -213,15 +213,58 @@ public extension DisappearingMessagesConfiguration {
// MARK: - Control Message // MARK: - Control Message
public extension DisappearingMessagesConfiguration { public extension DisappearingMessagesConfiguration {
static func insertControlMessage( func clearUnrelatedControlMessages(
_ db: Database,
threadVariant: SessionThread.Variant,
using dependencies: Dependencies = Dependencies()
) throws {
guard threadVariant == .contact else {
try Interaction
.filter(Interaction.Columns.threadId == self.threadId)
.filter(Interaction.Columns.variant == Interaction.Variant.infoDisappearingMessagesUpdate)
.filter(Interaction.Columns.expiresInSeconds != self.durationSeconds)
.deleteAll(db)
return
}
let userPublicKey: String = getUserHexEncodedPublicKey(db, using: dependencies)
guard self.isEnabled else {
try Interaction
.filter(Interaction.Columns.threadId == self.threadId)
.filter(Interaction.Columns.variant == Interaction.Variant.infoDisappearingMessagesUpdate)
.filter(Interaction.Columns.authorId == userPublicKey)
.filter(Interaction.Columns.expiresInSeconds != 0)
.deleteAll(db)
return
}
switch self.type {
case .disappearAfterRead:
try Interaction
.filter(Interaction.Columns.threadId == self.threadId)
.filter(Interaction.Columns.variant == Interaction.Variant.infoDisappearingMessagesUpdate)
.filter(Interaction.Columns.authorId == userPublicKey)
.filter(!(Interaction.Columns.expiresInSeconds == self.durationSeconds && Interaction.Columns.expiresStartedAtMs != Interaction.Columns.timestampMs))
.deleteAll(db)
case .disappearAfterSend:
try Interaction
.filter(Interaction.Columns.threadId == self.threadId)
.filter(Interaction.Columns.variant == Interaction.Variant.infoDisappearingMessagesUpdate)
.filter(Interaction.Columns.authorId == userPublicKey)
.filter(!(Interaction.Columns.expiresInSeconds == self.durationSeconds && Interaction.Columns.expiresStartedAtMs == Interaction.Columns.timestampMs))
.deleteAll(db)
default:
break
}
}
func insertControlMessage(
_ db: Database, _ db: Database,
threadId: String,
threadVariant: SessionThread.Variant, threadVariant: SessionThread.Variant,
authorId: String, authorId: String,
timestampMs: Int64, timestampMs: Int64,
serverHash: String?, serverHash: String?,
serverExpirationTimestamp: TimeInterval?, serverExpirationTimestamp: TimeInterval?,
updatedConfiguration: DisappearingMessagesConfiguration,
using dependencies: Dependencies = Dependencies() using dependencies: Dependencies = Dependencies()
) throws -> Int64? { ) throws -> Int64? {
if Features.useNewDisappearingMessagesConfig { if Features.useNewDisappearingMessagesConfig {
@ -256,21 +299,21 @@ public extension DisappearingMessagesConfiguration {
let messageExpirationInfo: Message.MessageExpirationInfo = Message.getMessageExpirationInfo( let messageExpirationInfo: Message.MessageExpirationInfo = Message.getMessageExpirationInfo(
wasRead: wasRead, wasRead: wasRead,
serverExpirationTimestamp: serverExpirationTimestamp, serverExpirationTimestamp: serverExpirationTimestamp,
expiresInSeconds: updatedConfiguration.durationSeconds, expiresInSeconds: self.durationSeconds,
expiresStartedAtMs: (updatedConfiguration.type == .disappearAfterSend) ? Double(timestampMs) : nil expiresStartedAtMs: (self.type == .disappearAfterSend) ? Double(timestampMs) : nil
) )
let interaction = try Interaction( let interaction = try Interaction(
serverHash: serverHash, serverHash: serverHash,
threadId: threadId, threadId: threadId,
authorId: authorId, authorId: authorId,
variant: .infoDisappearingMessagesUpdate, variant: .infoDisappearingMessagesUpdate,
body: updatedConfiguration.messageInfoString( body: self.messageInfoString(
threadVariant: threadVariant, threadVariant: threadVariant,
senderName: (authorId != getUserHexEncodedPublicKey(db) ? Profile.displayName(db, id: authorId) : nil) senderName: (authorId != getUserHexEncodedPublicKey(db) ? Profile.displayName(db, id: authorId) : nil)
), ),
timestampMs: timestampMs, timestampMs: timestampMs,
wasRead: wasRead, wasRead: wasRead,
expiresInSeconds: (threadVariant == .legacyGroup ? nil : updatedConfiguration.durationSeconds), // Do not expire this control message in legacy groups expiresInSeconds: (threadVariant == .legacyGroup ? nil : messageExpirationInfo.expiresInSeconds), // Do not expire this control message in legacy groups
expiresStartedAtMs: (threadVariant == .legacyGroup ? nil : messageExpirationInfo.expiresStartedAtMs) expiresStartedAtMs: (threadVariant == .legacyGroup ? nil : messageExpirationInfo.expiresStartedAtMs)
).inserted(db) ).inserted(db)

@ -191,15 +191,13 @@ extension MessageReceiver {
if threadId == getUserHexEncodedPublicKey(db) && updatedConfig != localConfig { if threadId == getUserHexEncodedPublicKey(db) && updatedConfig != localConfig {
return return
} }
_ = try DisappearingMessagesConfiguration.insertControlMessage( _ = try updatedConfig.insertControlMessage(
db, db,
threadId: threadId,
threadVariant: threadVariant, threadVariant: threadVariant,
authorId: sender, authorId: sender,
timestampMs: Int64(timestampMs), timestampMs: Int64(timestampMs),
serverHash: message.serverHash, serverHash: message.serverHash,
serverExpirationTimestamp: serverExpirationTimestamp, serverExpirationTimestamp: serverExpirationTimestamp
updatedConfiguration: updatedConfig
) )
default: default:
return return

@ -182,12 +182,12 @@ internal extension SessionUtil {
let isValid: Bool = Features.useNewDisappearingMessagesConfig ? data.config.isValidV2Config() : true let isValid: Bool = Features.useNewDisappearingMessagesConfig ? data.config.isValidV2Config() : true
if isValid && data.config != localConfig { if isValid && data.config != localConfig {
_ = try data.config.save(db) try data.config
_ = try Interaction .saved(db)
.filter(Interaction.Columns.threadId == sessionId) .clearUnrelatedControlMessages(
.filter(Interaction.Columns.variant == Interaction.Variant.infoDisappearingMessagesUpdate) db,
.filter(Interaction.Columns.authorId == getUserHexEncodedPublicKey(db)) threadVariant: .contact
.deleteAll(db) )
} }
} }

@ -278,12 +278,12 @@ internal extension SessionUtil {
.defaulting(to: DisappearingMessagesConfiguration.defaultWith(group.id)) .defaulting(to: DisappearingMessagesConfiguration.defaultWith(group.id))
if let updatedConfig = group.disappearingConfig, localConfig != updatedConfig { if let updatedConfig = group.disappearingConfig, localConfig != updatedConfig {
_ = try updatedConfig.save(db) try updatedConfig
.saved(db)
_ = try Interaction .clearUnrelatedControlMessages(
.filter(Interaction.Columns.threadId == group.id) db,
.filter(Interaction.Columns.variant == Interaction.Variant.infoDisappearingMessagesUpdate) threadVariant: .legacyGroup
.deleteAll(db) )
} }
// Update the members // Update the members

@ -133,11 +133,12 @@ internal extension SessionUtil {
.defaulting(to: DisappearingMessagesConfiguration.defaultWith(userPublicKey)) .defaulting(to: DisappearingMessagesConfiguration.defaultWith(userPublicKey))
if targetConfig != localConfig { if targetConfig != localConfig {
_ = try targetConfig.save(db) try targetConfig
_ = try Interaction .saved(db)
.filter(Interaction.Columns.threadId == userPublicKey) .clearUnrelatedControlMessages(
.filter(Interaction.Columns.variant == Interaction.Variant.infoDisappearingMessagesUpdate) db,
.deleteAll(db) threadVariant: .contact
)
} }
// Update settings if needed // Update settings if needed

Loading…
Cancel
Save