mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Merge pull request #599 from mpretty-cyro/fix/update-last-message-hash-after-registering-jobs
Fix - Update last message hash after registering jobs
This commit is contained in:
commit
7cd0079b37
4 changed files with 29 additions and 27 deletions
|
@ -42,7 +42,7 @@ public final class BackgroundPoller : NSObject {
|
|||
guard let snode = swarm.randomElement() else { throw SnodeAPI.Error.generic }
|
||||
return attempt(maxRetryCount: 4, recoveringOn: DispatchQueue.main) {
|
||||
return SnodeAPI.getRawMessages(from: snode, associatedWith: publicKey).then(on: DispatchQueue.main) { rawResponse -> Promise<Void> in
|
||||
let messages = SnodeAPI.parseRawMessagesResponse(rawResponse, from: snode, associatedWith: publicKey)
|
||||
let (messages, lastRawMessage) = SnodeAPI.parseRawMessagesResponse(rawResponse, from: snode, associatedWith: publicKey)
|
||||
let promises = messages.compactMap { json -> Promise<Void>? in
|
||||
// Use a best attempt approach here; we don't want to fail the entire process if one of the
|
||||
// messages failed to parse.
|
||||
|
@ -51,6 +51,10 @@ public final class BackgroundPoller : NSObject {
|
|||
let job = MessageReceiveJob(data: data, serverHash: json["hash"] as? String, isBackgroundPoll: true)
|
||||
return job.execute()
|
||||
}
|
||||
|
||||
// Now that the MessageReceiveJob's have been created we can update the `lastMessageHash` value
|
||||
SnodeAPI.updateLastMessageHashValueIfPossible(for: snode, associatedWith: publicKey, from: lastRawMessage)
|
||||
|
||||
return when(fulfilled: promises) // The promise returned by MessageReceiveJob never rejects
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,15 +100,17 @@ public final class ClosedGroupPoller : NSObject {
|
|||
|
||||
private func poll(_ groupPublicKey: String) -> Promise<Void> {
|
||||
guard isPolling(for: groupPublicKey) else { return Promise.value(()) }
|
||||
let promise = SnodeAPI.getSwarm(for: groupPublicKey).then2 { [weak self] swarm -> Promise<[JSON]> in
|
||||
let promise = SnodeAPI.getSwarm(for: groupPublicKey).then2 { [weak self] swarm -> Promise<(Snode, [JSON], JSON?)> in
|
||||
// randomElement() uses the system's default random generator, which is cryptographically secure
|
||||
guard let snode = swarm.randomElement() else { return Promise(error: Error.insufficientSnodes) }
|
||||
guard let self = self, self.isPolling(for: groupPublicKey) else { return Promise(error: Error.pollingCanceled) }
|
||||
return SnodeAPI.getRawMessages(from: snode, associatedWith: groupPublicKey).map2 {
|
||||
SnodeAPI.parseRawMessagesResponse($0, from: snode, associatedWith: groupPublicKey)
|
||||
let (rawMessages, lastRawMessage) = SnodeAPI.parseRawMessagesResponse($0, from: snode, associatedWith: groupPublicKey)
|
||||
|
||||
return (snode, rawMessages, lastRawMessage)
|
||||
}
|
||||
}
|
||||
promise.done2 { [weak self] rawMessages in
|
||||
promise.done2 { [weak self] snode, rawMessages, lastRawMessage in
|
||||
guard let self = self, self.isPolling(for: groupPublicKey) else { return }
|
||||
if !rawMessages.isEmpty {
|
||||
SNLog("Received \(rawMessages.count) new message(s) in closed group with public key: \(groupPublicKey).")
|
||||
|
@ -125,6 +127,9 @@ public final class ClosedGroupPoller : NSObject {
|
|||
SNLog("Failed to deserialize envelope due to error: \(error).")
|
||||
}
|
||||
}
|
||||
|
||||
// Now that the MessageReceiveJob's have been created we can update the `lastMessageHash` value
|
||||
SnodeAPI.updateLastMessageHashValueIfPossible(for: snode, associatedWith: groupPublicKey, from: lastRawMessage)
|
||||
}
|
||||
promise.catch2 { error in
|
||||
SNLog("Polling failed for closed group with public key: \(groupPublicKey) due to error: \(error).")
|
||||
|
|
|
@ -94,7 +94,7 @@ public final class Poller : NSObject {
|
|||
let userPublicKey = getUserHexEncodedPublicKey()
|
||||
return SnodeAPI.getRawMessages(from: snode, associatedWith: userPublicKey).then(on: Threading.pollerQueue) { [weak self] rawResponse -> Promise<Void> in
|
||||
guard let strongSelf = self, strongSelf.isPolling else { return Promise { $0.fulfill(()) } }
|
||||
let messages = SnodeAPI.parseRawMessagesResponse(rawResponse, from: snode, associatedWith: userPublicKey)
|
||||
let (messages, lastRawMessage) = SnodeAPI.parseRawMessagesResponse(rawResponse, from: snode, associatedWith: userPublicKey)
|
||||
if !messages.isEmpty {
|
||||
SNLog("Received \(messages.count) new message(s).")
|
||||
}
|
||||
|
@ -110,6 +110,10 @@ public final class Poller : NSObject {
|
|||
SNLog("Failed to deserialize envelope due to error: \(error).")
|
||||
}
|
||||
}
|
||||
|
||||
// Now that the MessageReceiveJob's have been created we can update the `lastMessageHash` value
|
||||
SnodeAPI.updateLastMessageHashValueIfPossible(for: snode, associatedWith: userPublicKey, from: lastRawMessage)
|
||||
|
||||
strongSelf.pollCount += 1
|
||||
if strongSelf.pollCount == Poller.maxPollCount {
|
||||
throw Error.pollLimitReached
|
||||
|
|
|
@ -398,20 +398,6 @@ public final class SnodeAPI : NSObject {
|
|||
return promise
|
||||
}
|
||||
|
||||
public static func getMessages(for publicKey: String) -> Promise<Set<MessageListPromise>> {
|
||||
let (promise, seal) = Promise<Set<MessageListPromise>>.pending()
|
||||
Threading.workQueue.async {
|
||||
attempt(maxRetryCount: maxRetryCount, recoveringOn: Threading.workQueue) {
|
||||
getTargetSnodes(for: publicKey).mapValues2 { targetSnode in
|
||||
return getMessagesInternal(from: targetSnode, associatedWith: publicKey).map2 { rawResponse in
|
||||
parseRawMessagesResponse(rawResponse, from: targetSnode, associatedWith: publicKey)
|
||||
}
|
||||
}.map2 { Set($0) }
|
||||
}.done2 { seal.fulfill($0) }.catch2 { seal.reject($0) }
|
||||
}
|
||||
return promise
|
||||
}
|
||||
|
||||
private static func getMessagesInternal(from snode: Snode, associatedWith publicKey: String) -> RawResponsePromise {
|
||||
let storage = SNSnodeKitConfiguration.shared.storage
|
||||
|
||||
|
@ -573,20 +559,23 @@ public final class SnodeAPI : NSObject {
|
|||
})
|
||||
}
|
||||
|
||||
public static func parseRawMessagesResponse(_ rawResponse: Any, from snode: Snode, associatedWith publicKey: String) -> [JSON] {
|
||||
guard let json = rawResponse as? JSON, let rawMessages = json["messages"] as? [JSON] else { return [] }
|
||||
updateLastMessageHashValueIfPossible(for: snode, associatedWith: publicKey, from: rawMessages)
|
||||
return removeDuplicates(from: rawMessages, associatedWith: publicKey)
|
||||
public static func parseRawMessagesResponse(_ rawResponse: Any, from snode: Snode, associatedWith publicKey: String) -> (messages: [JSON], lastRawMessage: JSON?) {
|
||||
guard let json = rawResponse as? JSON, let rawMessages = json["messages"] as? [JSON] else { return ([], nil) }
|
||||
|
||||
return (
|
||||
removeDuplicates(from: rawMessages, associatedWith: publicKey),
|
||||
rawMessages.last
|
||||
)
|
||||
}
|
||||
|
||||
private static func updateLastMessageHashValueIfPossible(for snode: Snode, associatedWith publicKey: String, from rawMessages: [JSON]) {
|
||||
if let lastMessage = rawMessages.last, let lastHash = lastMessage["hash"] as? String, let expirationDate = lastMessage["expiration"] as? UInt64 {
|
||||
public static func updateLastMessageHashValueIfPossible(for snode: Snode, associatedWith publicKey: String, from lastRawMessage: JSON?) {
|
||||
if let lastMessage = lastRawMessage, let lastHash = lastMessage["hash"] as? String, let expirationDate = lastMessage["expiration"] as? UInt64 {
|
||||
SNSnodeKitConfiguration.shared.storage.writeSync { transaction in
|
||||
SNSnodeKitConfiguration.shared.storage.setLastMessageHashInfo(for: snode, associatedWith: publicKey,
|
||||
to: [ "hash" : lastHash, "expirationDate" : NSNumber(value: expirationDate) ], using: transaction)
|
||||
}
|
||||
} else if (!rawMessages.isEmpty) {
|
||||
SNLog("Failed to update last message hash value from: \(rawMessages).")
|
||||
} else if (lastRawMessage != nil) {
|
||||
SNLog("Failed to update last message hash value from: \(String(describing: lastRawMessage)).")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue