Try to use group changes when learning of a v2 group.
This commit is contained in:
parent
e937fe02c7
commit
bb28184289
@ -20,12 +20,8 @@ public class GroupV2UpdatesImpl: NSObject, GroupV2UpdatesSwift {
|
||||
return SSKEnvironment.shared.messageProcessing
|
||||
}
|
||||
|
||||
private var groupsV2: GroupsV2 {
|
||||
return SSKEnvironment.shared.groupsV2
|
||||
}
|
||||
|
||||
private var groupsV2Swift: GroupsV2Swift {
|
||||
return self.groupsV2 as! GroupsV2Swift
|
||||
private var groupsV2: GroupsV2Swift {
|
||||
return SSKEnvironment.shared.groupsV2 as! GroupsV2Swift
|
||||
}
|
||||
|
||||
private var tsAccountManager: TSAccountManager {
|
||||
@ -305,15 +301,25 @@ public class GroupV2UpdatesImpl: NSObject, GroupV2UpdatesSwift {
|
||||
return self.fetchAndApplyChangeActionsFromService(groupSecretParamsData: groupSecretParamsData,
|
||||
groupUpdateMode: groupUpdateMode)
|
||||
.recover { (error) throws -> Promise<TSGroupThread> in
|
||||
switch error {
|
||||
case GroupsV2Error.groupNotInDatabase:
|
||||
// Unknown groups are handled by snapshot.
|
||||
break
|
||||
default:
|
||||
owsFailDebug("Error: \(error)")
|
||||
}
|
||||
let shouldTrySnapshot = { () -> Bool in
|
||||
// GroupsV2 TODO: This should not fail over in the case of networking problems.
|
||||
switch error {
|
||||
case GroupsV2Error.groupNotInDatabase:
|
||||
// Unknown groups are handled by snapshot.
|
||||
return true
|
||||
case GroupsV2Error.unauthorized:
|
||||
// We can recover from some auth edge cases
|
||||
// using a snapshot.
|
||||
return true
|
||||
default:
|
||||
owsFailDebug("Error: \(error)")
|
||||
return false
|
||||
}
|
||||
}()
|
||||
|
||||
// GroupsV2 TODO: This should not fail over in the case of networking problems.
|
||||
guard shouldTrySnapshot else {
|
||||
throw error
|
||||
}
|
||||
|
||||
// Failover to applying latest snapshot.
|
||||
return self.fetchAndApplyCurrentGroupV2SnapshotFromService(groupSecretParamsData: groupSecretParamsData,
|
||||
@ -362,7 +368,7 @@ public class GroupV2UpdatesImpl: NSObject, GroupV2UpdatesSwift {
|
||||
let updatedGroupThread = try GroupManager.updateExistingGroupThreadInDatabaseAndCreateInfoMessage(groupThread: groupThread,
|
||||
newGroupModel: changedGroupModel.newGroupModel,
|
||||
groupUpdateSourceAddress: groupUpdateSourceAddress,
|
||||
transaction: transaction).groupThread
|
||||
transaction: transaction).groupThread
|
||||
|
||||
GroupManager.storeProfileKeysFromGroupProtos(changedGroupModel.profileKeys)
|
||||
|
||||
@ -377,9 +383,17 @@ public class GroupV2UpdatesImpl: NSObject, GroupV2UpdatesSwift {
|
||||
|
||||
private func fetchAndApplyChangeActionsFromService(groupSecretParamsData: Data,
|
||||
groupUpdateMode: GroupUpdateMode) -> Promise<TSGroupThread> {
|
||||
return firstly {
|
||||
groupsV2Swift.fetchGroupChangeActions(groupSecretParamsData: groupSecretParamsData)
|
||||
}.then(on: DispatchQueue.global()) { (groupChanges) throws -> Promise<TSGroupThread> in
|
||||
return firstly { () -> Promise<[GroupV2Change]> in
|
||||
var firstKnownRevision: UInt32?
|
||||
switch groupUpdateMode {
|
||||
case .upToSpecificRevisionImmediately(let upToRevision):
|
||||
firstKnownRevision = upToRevision
|
||||
default:
|
||||
break
|
||||
}
|
||||
return self.groupsV2.fetchGroupChangeActions(groupSecretParamsData: groupSecretParamsData,
|
||||
firstKnownRevision: firstKnownRevision)
|
||||
}.then(on: DispatchQueue.global()) { (groupChanges: [GroupV2Change]) throws -> Promise<TSGroupThread> in
|
||||
let groupId = try self.groupsV2.groupId(forGroupSecretParamsData: groupSecretParamsData)
|
||||
return self.tryToApplyGroupChangesFromService(groupId: groupId,
|
||||
groupChanges: groupChanges,
|
||||
@ -462,7 +476,7 @@ public class GroupV2UpdatesImpl: NSObject, GroupV2UpdatesSwift {
|
||||
groupThread = try GroupManager.updateExistingGroupThreadInDatabaseAndCreateInfoMessage(groupThread: groupThread,
|
||||
newGroupModel: newGroupModel,
|
||||
groupUpdateSourceAddress: groupUpdateSourceAddress,
|
||||
transaction: transaction).groupThread
|
||||
transaction: transaction).groupThread
|
||||
|
||||
}
|
||||
return groupThread
|
||||
@ -474,7 +488,7 @@ public class GroupV2UpdatesImpl: NSObject, GroupV2UpdatesSwift {
|
||||
private func fetchAndApplyCurrentGroupV2SnapshotFromService(groupSecretParamsData: Data,
|
||||
groupUpdateMode: GroupUpdateMode) -> Promise<TSGroupThread> {
|
||||
return firstly {
|
||||
self.groupsV2Swift.fetchCurrentGroupV2Snapshot(groupSecretParamsData: groupSecretParamsData)
|
||||
self.groupsV2.fetchCurrentGroupV2Snapshot(groupSecretParamsData: groupSecretParamsData)
|
||||
}.then(on: .global()) { groupV2Snapshot in
|
||||
return self.tryToApplyCurrentGroupV2SnapshotFromService(groupV2Snapshot: groupV2Snapshot,
|
||||
groupUpdateMode: groupUpdateMode)
|
||||
@ -502,9 +516,9 @@ public class GroupV2UpdatesImpl: NSObject, GroupV2UpdatesSwift {
|
||||
// author(s) of changes reflected in the snapshot.
|
||||
let groupUpdateSourceAddress: SignalServiceAddress? = nil
|
||||
let result = try GroupManager.tryToUpsertExistingGroupThreadInDatabaseAndCreateInfoMessage(newGroupModel: newGroupModel,
|
||||
groupUpdateSourceAddress: groupUpdateSourceAddress,
|
||||
canInsert: true,
|
||||
transaction: transaction)
|
||||
groupUpdateSourceAddress: groupUpdateSourceAddress,
|
||||
canInsert: true,
|
||||
transaction: transaction)
|
||||
|
||||
GroupManager.storeProfileKeysFromGroupProtos(groupV2Snapshot.profileKeys)
|
||||
|
||||
|
||||
@ -271,7 +271,8 @@ public class GroupsV2Impl: NSObject, GroupsV2Swift {
|
||||
|
||||
// MARK: - Fetch Group Change Actions
|
||||
|
||||
public func fetchGroupChangeActions(groupSecretParamsData: Data) -> Promise<[GroupV2Change]> {
|
||||
public func fetchGroupChangeActions(groupSecretParamsData: Data,
|
||||
firstKnownRevision: UInt32?) -> Promise<[GroupV2Change]> {
|
||||
guard let localUuid = tsAccountManager.localUuid else {
|
||||
return Promise(error: OWSAssertionError("Missing localUuid."))
|
||||
}
|
||||
@ -282,19 +283,25 @@ public class GroupsV2Impl: NSObject, GroupsV2Swift {
|
||||
}.then(on: DispatchQueue.global()) { (groupId: Data, groupV2Params: GroupV2Params) -> Promise<[GroupV2Change]> in
|
||||
return self.fetchGroupChangeActions(groupId: groupId,
|
||||
groupV2Params: groupV2Params,
|
||||
localUuid: localUuid)
|
||||
localUuid: localUuid,
|
||||
firstKnownRevision: firstKnownRevision)
|
||||
}
|
||||
}
|
||||
|
||||
private func fetchGroupChangeActions(groupId: Data,
|
||||
groupV2Params: GroupV2Params,
|
||||
localUuid: UUID) -> Promise<[GroupV2Change]> {
|
||||
localUuid: UUID,
|
||||
firstKnownRevision: UInt32?) -> Promise<[GroupV2Change]> {
|
||||
|
||||
let requestBuilder: RequestBuilder = { (authCredential, sessionManager) in
|
||||
return DispatchQueue.global().async(.promise) { () -> NSURLRequest in
|
||||
let fromRevision = try self.databaseStorage.read { (transaction) throws -> UInt32 in
|
||||
guard let groupThread = TSGroupThread.fetch(groupId: groupId, transaction: transaction) else {
|
||||
// This probably isn't an error and will be handled upstream.
|
||||
if let firstKnownRevision = firstKnownRevision {
|
||||
Logger.info("Group not in database, using first known revision.")
|
||||
return firstKnownRevision
|
||||
}
|
||||
throw GroupsV2Error.groupNotInDatabase
|
||||
}
|
||||
guard groupThread.groupModel.groupsVersion == .V2 else {
|
||||
|
||||
@ -589,8 +589,8 @@ class IncomingGroupsV2MessageQueue: NSObject {
|
||||
let groupUpdateMode = GroupUpdateMode.upToSpecificRevisionImmediately(upToRevision: groupContext.revision)
|
||||
return firstly {
|
||||
groupV2UpdatesSwift.tryToRefreshV2GroupThreadWithThrottling(groupId: groupContextInfo.groupId,
|
||||
groupSecretParamsData: groupContextInfo.groupSecretParamsData,
|
||||
groupUpdateMode: groupUpdateMode)
|
||||
groupSecretParamsData: groupContextInfo.groupSecretParamsData,
|
||||
groupUpdateMode: groupUpdateMode)
|
||||
}.map(on: .global()) { (_) in
|
||||
return UpdateOutcome.successShouldProcess
|
||||
}.recover(on: .global()) { error -> Guarantee<UpdateOutcome> in
|
||||
|
||||
@ -55,7 +55,8 @@ public protocol GroupsV2Swift: GroupsV2 {
|
||||
|
||||
func fetchCurrentGroupV2Snapshot(groupSecretParamsData: Data) -> Promise<GroupV2Snapshot>
|
||||
|
||||
func fetchGroupChangeActions(groupSecretParamsData: Data) -> Promise<[GroupV2Change]>
|
||||
func fetchGroupChangeActions(groupSecretParamsData: Data,
|
||||
firstKnownRevision: UInt32?) -> Promise<[GroupV2Change]>
|
||||
|
||||
func buildChangeSet(oldGroupModel: TSGroupModel,
|
||||
newGroupModel: TSGroupModel,
|
||||
@ -94,6 +95,8 @@ public enum GroupUpdateMode {
|
||||
// * Group update should halt at a specific revision.
|
||||
// * Group update _should not_ block on message processing.
|
||||
// * Group update _should not_ be throttled.
|
||||
//
|
||||
// upToRevision is inclusive.
|
||||
case upToSpecificRevisionImmediately(upToRevision: UInt32)
|
||||
// * Group update should continue until current revision.
|
||||
// * Group update _should_ block on message processing.
|
||||
@ -222,7 +225,8 @@ public class MockGroupsV2: NSObject, GroupsV2, GroupsV2Swift {
|
||||
owsFail("Not implemented.")
|
||||
}
|
||||
|
||||
public func fetchGroupChangeActions(groupSecretParamsData: Data) -> Promise<[GroupV2Change]> {
|
||||
public func fetchGroupChangeActions(groupSecretParamsData: Data,
|
||||
firstKnownRevision: UInt32?) -> Promise<[GroupV2Change]> {
|
||||
owsFail("Not implemented.")
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user