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

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

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

@ -213,15 +213,58 @@ public extension DisappearingMessagesConfiguration {
// MARK: - Control Message
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,
threadId: String,
threadVariant: SessionThread.Variant,
authorId: String,
timestampMs: Int64,
serverHash: String?,
serverExpirationTimestamp: TimeInterval?,
updatedConfiguration: DisappearingMessagesConfiguration,
using dependencies: Dependencies = Dependencies()
) throws -> Int64? {
if Features.useNewDisappearingMessagesConfig {
@ -256,21 +299,21 @@ public extension DisappearingMessagesConfiguration {
let messageExpirationInfo: Message.MessageExpirationInfo = Message.getMessageExpirationInfo(
wasRead: wasRead,
serverExpirationTimestamp: serverExpirationTimestamp,
expiresInSeconds: updatedConfiguration.durationSeconds,
expiresStartedAtMs: (updatedConfiguration.type == .disappearAfterSend) ? Double(timestampMs) : nil
expiresInSeconds: self.durationSeconds,
expiresStartedAtMs: (self.type == .disappearAfterSend) ? Double(timestampMs) : nil
)
let interaction = try Interaction(
serverHash: serverHash,
threadId: threadId,
authorId: authorId,
variant: .infoDisappearingMessagesUpdate,
body: updatedConfiguration.messageInfoString(
body: self.messageInfoString(
threadVariant: threadVariant,
senderName: (authorId != getUserHexEncodedPublicKey(db) ? Profile.displayName(db, id: authorId) : nil)
),
timestampMs: timestampMs,
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)
).inserted(db)

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

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

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

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

Loading…
Cancel
Save