From 2f73692d65c3feb78c3d9553e1a3d1e9587ba720 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Thu, 27 Jul 2023 21:57:47 +0400 Subject: [PATCH] Allow getStoriesById to fail in state resolution --- .../Sources/Network/Download.swift | 8 ++++- .../State/AccountStateManagementUtils.swift | 32 +++++++++++-------- .../TelegramCore/Sources/State/Holes.swift | 10 +++--- .../TelegramEngine/Messages/Stories.swift | 17 ++++++---- 4 files changed, 40 insertions(+), 27 deletions(-) diff --git a/submodules/TelegramCore/Sources/Network/Download.swift b/submodules/TelegramCore/Sources/Network/Download.swift index ede8908135..2ebe6cff22 100644 --- a/submodules/TelegramCore/Sources/Network/Download.swift +++ b/submodules/TelegramCore/Sources/Network/Download.swift @@ -295,7 +295,7 @@ class Download: NSObject, MTRequestMessageServiceDelegate { |> retryRequest } - func request(_ data: (FunctionDescription, Buffer, DeserializeFunctionResponse), expectedResponseSize: Int32? = nil) -> Signal { + func request(_ data: (FunctionDescription, Buffer, DeserializeFunctionResponse), expectedResponseSize: Int32? = nil, automaticFloodWait: Bool = true) -> Signal { return Signal { subscriber in let request = MTRequest() request.expectedResponseSize = expectedResponseSize ?? 0 @@ -311,6 +311,12 @@ class Download: NSObject, MTRequestMessageServiceDelegate { request.needsTimeoutTimer = self.useRequestTimeoutTimers request.shouldContinueExecutionWithErrorContext = { errorContext in + guard let errorContext = errorContext else { + return true + } + if errorContext.floodWaitSeconds > 0 && !automaticFloodWait { + return false + } return true } diff --git a/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift b/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift index 346d282ab2..8da7bf5308 100644 --- a/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift +++ b/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift @@ -2100,25 +2100,29 @@ func resolveStories(postbox: Postbox, source: FetchMessageHistoryHoleSource, while idOffset < allIds.count { let bucketLength = min(100, allIds.count - idOffset) let ids = Array(allIds[idOffset ..< (idOffset + bucketLength)]) - signals.append(_internal_getStoriesById(accountPeerId: accountPeerId, postbox: postbox, source: source, peerId: peerId, peerReference: additionalPeers.get(peerId).flatMap(PeerReference.init), ids: ids) + signals.append(_internal_getStoriesById(accountPeerId: accountPeerId, postbox: postbox, source: source, peerId: peerId, peerReference: additionalPeers.get(peerId).flatMap(PeerReference.init), ids: ids, allowFloodWait: false) |> mapToSignal { result -> Signal in - return postbox.transaction { transaction -> Void in - for id in ids { - let current = transaction.getStory(id: StoryId(peerId: peerId, id: id)) - var updated: CodableEntry? - if let updatedItem = result.first(where: { $0.id == id }) { - if let entry = CodableEntry(updatedItem) { - updated = entry + if let result = result { + return postbox.transaction { transaction -> Void in + for id in ids { + let current = transaction.getStory(id: StoryId(peerId: peerId, id: id)) + var updated: CodableEntry? + if let updatedItem = result.first(where: { $0.id == id }) { + if let entry = CodableEntry(updatedItem) { + updated = entry + } + } else { + updated = CodableEntry(data: Data()) + } + if current != updated { + transaction.setStory(id: StoryId(peerId: peerId, id: id), value: updated ?? CodableEntry(data: Data())) } - } else { - updated = CodableEntry(data: Data()) - } - if current != updated { - transaction.setStory(id: StoryId(peerId: peerId, id: id), value: updated ?? CodableEntry(data: Data())) } } + |> ignoreValues + } else { + return .complete() } - |> ignoreValues }) idOffset += bucketLength } diff --git a/submodules/TelegramCore/Sources/State/Holes.swift b/submodules/TelegramCore/Sources/State/Holes.swift index bb5f62e31c..88d9054a43 100644 --- a/submodules/TelegramCore/Sources/State/Holes.swift +++ b/submodules/TelegramCore/Sources/State/Holes.swift @@ -108,12 +108,12 @@ enum FetchMessageHistoryHoleSource { case network(Network) case download(Download) - func request(_ data: (FunctionDescription, Buffer, DeserializeFunctionResponse)) -> Signal { + func request(_ data: (FunctionDescription, Buffer, DeserializeFunctionResponse), automaticFloodWait: Bool = true) -> Signal { switch self { - case let .network(network): - return network.request(data) - case let .download(download): - return download.request(data) + case let .network(network): + return network.request(data, automaticFloodWait: automaticFloodWait) + case let .download(download): + return download.request(data, automaticFloodWait: automaticFloodWait) } } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/Stories.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/Stories.swift index ee462a3aa5..90477761d3 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/Stories.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/Stories.swift @@ -1435,25 +1435,25 @@ func _internal_getStoriesById(accountPeerId: PeerId, postbox: Postbox, network: } } -func _internal_getStoriesById(accountPeerId: PeerId, postbox: Postbox, source: FetchMessageHistoryHoleSource, peerId: PeerId, peerReference: PeerReference?, ids: [Int32]) -> Signal<[Stories.StoredItem], NoError> { +func _internal_getStoriesById(accountPeerId: PeerId, postbox: Postbox, source: FetchMessageHistoryHoleSource, peerId: PeerId, peerReference: PeerReference?, ids: [Int32], allowFloodWait: Bool) -> Signal<[Stories.StoredItem]?, NoError> { return postbox.transaction { transaction -> Api.InputUser? in return transaction.getPeer(peerId).flatMap(apiInputUser) } - |> mapToSignal { inputUser -> Signal<[Stories.StoredItem], NoError> in + |> mapToSignal { inputUser -> Signal<[Stories.StoredItem]?, NoError> in guard let inputUser = inputUser ?? peerReference?.inputUser else { return .single([]) } - return source.request(Api.functions.stories.getStoriesByID(userId: inputUser, id: ids)) + return source.request(Api.functions.stories.getStoriesByID(userId: inputUser, id: ids), automaticFloodWait: allowFloodWait) |> map(Optional.init) |> `catch` { _ -> Signal in return .single(nil) } - |> mapToSignal { result -> Signal<[Stories.StoredItem], NoError> in + |> mapToSignal { result -> Signal<[Stories.StoredItem]?, NoError> in guard let result = result else { - return .single([]) + return .single(nil) } - return postbox.transaction { transaction -> [Stories.StoredItem] in + return postbox.transaction { transaction -> [Stories.StoredItem]? in switch result { case let .stories(_, stories, users): updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: AccumulatedPeers(users: users)) @@ -1904,8 +1904,11 @@ func _internal_exportStoryLink(account: Account, peerId: EnginePeer.Id, id: Int3 } func _internal_refreshStories(account: Account, peerId: PeerId, ids: [Int32]) -> Signal { - return _internal_getStoriesById(accountPeerId: account.peerId, postbox: account.postbox, source: .network(account.network), peerId: peerId, peerReference: nil, ids: ids) + return _internal_getStoriesById(accountPeerId: account.peerId, postbox: account.postbox, source: .network(account.network), peerId: peerId, peerReference: nil, ids: ids, allowFloodWait: true) |> mapToSignal { result -> Signal in + guard let result = result else { + return .complete() + } return account.postbox.transaction { transaction -> Void in var currentItems = transaction.getStoryItems(peerId: peerId) for i in 0 ..< currentItems.count {