From 11629a068ad65975cd84c87b94e57ecb302a7b06 Mon Sep 17 00:00:00 2001 From: Peter Date: Sat, 15 Sep 2018 00:39:19 +0300 Subject: [PATCH] no message --- TelegramCore/CollectCacheUsageStats.swift | 2 - TelegramCore/Download.swift | 7 +- TelegramCore/FetchedMediaResource.swift | 94 +++++++++++-------- ...anagedSynchronizeSavedGifsOperations.swift | 2 +- ...edSynchronizeSavedStickersOperations.swift | 2 +- .../PendingMessageUploadedContent.swift | 2 +- TelegramCore/SearchMessages.swift | 6 +- 7 files changed, 66 insertions(+), 49 deletions(-) diff --git a/TelegramCore/CollectCacheUsageStats.swift b/TelegramCore/CollectCacheUsageStats.swift index 5d34cc2f6f..0e524a50f5 100644 --- a/TelegramCore/CollectCacheUsageStats.swift +++ b/TelegramCore/CollectCacheUsageStats.swift @@ -173,8 +173,6 @@ public func collectCacheUsageStats(account: Account) -> Signal CacheUsageStats in - - var peers: [PeerId: Peer] = [:] for peerId in finalMedia.keys { if let peer = transaction.getPeer(peerId) { diff --git a/TelegramCore/Download.swift b/TelegramCore/Download.swift index b6d11bce5e..3d623c1ee2 100644 --- a/TelegramCore/Download.swift +++ b/TelegramCore/Download.swift @@ -232,7 +232,6 @@ class Download: NSObject, MTRequestMessageServiceDelegate { } func request(_ data: (FunctionDescription, Buffer, DeserializeFunctionResponse)) -> Signal { - let requestService = self.requestService return Signal { subscriber in let request = MTRequest() @@ -261,10 +260,10 @@ class Download: NSObject, MTRequestMessageServiceDelegate { let internalId: Any! = request.internalId - requestService.add(request) + self.requestService.add(request) - return ActionDisposable { [weak requestService] in - requestService?.removeRequest(byInternalId: internalId) + return ActionDisposable { + self.requestService.removeRequest(byInternalId: internalId) } } } diff --git a/TelegramCore/FetchedMediaResource.swift b/TelegramCore/FetchedMediaResource.swift index 548d1c73b3..084b55d0db 100644 --- a/TelegramCore/FetchedMediaResource.swift +++ b/TelegramCore/FetchedMediaResource.swift @@ -423,18 +423,20 @@ extension MediaResourceReference { final class TelegramCloudMediaResourceFetchInfo: MediaResourceFetchInfo { let reference: MediaResourceReference + let preferBackgroundReferenceRevalidation: Bool - init(reference: MediaResourceReference) { + init(reference: MediaResourceReference, preferBackgroundReferenceRevalidation: Bool) { self.reference = reference + self.preferBackgroundReferenceRevalidation = preferBackgroundReferenceRevalidation } } -public func fetchedMediaResource(postbox: Postbox, reference: MediaResourceReference, range: Range? = nil, statsCategory: MediaResourceStatsCategory = .generic, reportResultStatus: Bool = false) -> Signal { +public func fetchedMediaResource(postbox: Postbox, reference: MediaResourceReference, range: Range? = nil, statsCategory: MediaResourceStatsCategory = .generic, reportResultStatus: Bool = false, preferBackgroundReferenceRevalidation: Bool = false) -> Signal { if let range = range { - return postbox.mediaBox.fetchedResourceData(reference.resource, in: range, parameters: MediaResourceFetchParameters(tag: TelegramMediaResourceFetchTag(statsCategory: statsCategory), info: TelegramCloudMediaResourceFetchInfo(reference: reference))) + return postbox.mediaBox.fetchedResourceData(reference.resource, in: range, parameters: MediaResourceFetchParameters(tag: TelegramMediaResourceFetchTag(statsCategory: statsCategory), info: TelegramCloudMediaResourceFetchInfo(reference: reference, preferBackgroundReferenceRevalidation: preferBackgroundReferenceRevalidation))) |> map { _ in .local } } else { - return postbox.mediaBox.fetchedResource(reference.resource, parameters: MediaResourceFetchParameters(tag: TelegramMediaResourceFetchTag(statsCategory: statsCategory), info: TelegramCloudMediaResourceFetchInfo(reference: reference)), implNext: reportResultStatus) + return postbox.mediaBox.fetchedResource(reference.resource, parameters: MediaResourceFetchParameters(tag: TelegramMediaResourceFetchTag(statsCategory: statsCategory), info: TelegramCloudMediaResourceFetchInfo(reference: reference, preferBackgroundReferenceRevalidation: preferBackgroundReferenceRevalidation)), implNext: reportResultStatus) } } @@ -550,43 +552,50 @@ private final class MediaReferenceRevalidationItemContext { } } +private struct MediaReferenceRevalidationKeyAndPlacement: Hashable { + let key: MediaReferenceRevalidationKey + let background: Bool +} + private final class MediaReferenceRevalidationContextImpl { let queue: Queue - var itemContexts: [MediaReferenceRevalidationKey: MediaReferenceRevalidationItemContext] = [:] + var itemContexts: [MediaReferenceRevalidationKeyAndPlacement: MediaReferenceRevalidationItemContext] = [:] init(queue: Queue) { self.queue = queue } - func genericItem(key: MediaReferenceRevalidationKey, request: @escaping (@escaping (Any) -> Void, @escaping (RevalidateMediaReferenceError) -> Void) -> Disposable, _ f: @escaping (Any) -> Void) -> Disposable { + func genericItem(key: MediaReferenceRevalidationKey, background: Bool, request: @escaping (@escaping (Any) -> Void, @escaping (RevalidateMediaReferenceError) -> Void) -> Disposable, _ f: @escaping (Any) -> Void) -> Disposable { let queue = self.queue + let itemKey = MediaReferenceRevalidationKeyAndPlacement(key: key, background: background) + let context: MediaReferenceRevalidationItemContext - if let current = self.itemContexts[key] { + if let current = self.itemContexts[itemKey] { context = current } else { let disposable = MetaDisposable() context = MediaReferenceRevalidationItemContext(disposable: disposable) - self.itemContexts[key] = context + self.itemContexts[itemKey] = context disposable.set(request({ [weak self] result in queue.async { guard let strongSelf = self else { return } - if let current = strongSelf.itemContexts[key], current === context { - strongSelf.itemContexts.removeValue(forKey: key) + if let current = strongSelf.itemContexts[itemKey], current === context { + strongSelf.itemContexts.removeValue(forKey: itemKey) for subscriber in current.subscribers.copyItems() { subscriber(result) } } } }, { [weak self] _ in - queue.async { + /*queue.async { guard let strongSelf = self else { return } - } + }*/ })) } @@ -597,11 +606,11 @@ private final class MediaReferenceRevalidationContextImpl { guard let strongSelf = self else { return } - if let current = strongSelf.itemContexts[key], current === context { + if let current = strongSelf.itemContexts[itemKey], current === context { current.removeSubscriber(index) if current.isEmpty { current.disposable.dispose() - strongSelf.itemContexts.removeValue(forKey: key) + strongSelf.itemContexts.removeValue(forKey: itemKey) } } } @@ -621,11 +630,11 @@ final class MediaReferenceRevalidationContext { }) } - private func genericItem(key: MediaReferenceRevalidationKey, request: @escaping (@escaping (Any) -> Void, @escaping (RevalidateMediaReferenceError) -> Void) -> Disposable) -> Signal { + private func genericItem(key: MediaReferenceRevalidationKey, background: Bool, request: @escaping (@escaping (Any) -> Void, @escaping (RevalidateMediaReferenceError) -> Void) -> Disposable) -> Signal { return Signal { subscriber in let disposable = MetaDisposable() self.impl.with { impl in - disposable.set(impl.genericItem(key: key, request: request, { result in + disposable.set(impl.genericItem(key: key, background: background, request: request, { result in subscriber.putNext(result) subscriber.putCompletion() })) @@ -634,9 +643,20 @@ final class MediaReferenceRevalidationContext { } } - func message(postbox: Postbox, network: Network, message: MessageReference) -> Signal { - return self.genericItem(key: .message(message: message), request: { next, error in - return fetchRemoteMessage(postbox: postbox, network: network, message: message).start(next: { value in + func message(postbox: Postbox, network: Network, background: Bool, message: MessageReference) -> Signal { + return self.genericItem(key: .message(message: message), background: background, request: { next, error in + let source: Signal + if background { + source = network.background() + |> map(FetchMessageHistoryHoleSource.download) + } else { + source = .single(.network(network)) + } + let signal = source + |> mapToSignal { source -> Signal in + return fetchRemoteMessage(postbox: postbox, source: source, message: message) + } + return signal.start(next: { value in if let value = value { next(value) } else { @@ -654,8 +674,8 @@ final class MediaReferenceRevalidationContext { } } - func stickerPack(postbox: Postbox, network: Network, stickerPack: StickerPackReference) -> Signal<(StickerPackCollectionInfo, [ItemCollectionItem]), RevalidateMediaReferenceError> { - return self.genericItem(key: .stickerPack(stickerPack: stickerPack), request: { next, error in + func stickerPack(postbox: Postbox, network: Network, background: Bool, stickerPack: StickerPackReference) -> Signal<(StickerPackCollectionInfo, [ItemCollectionItem]), RevalidateMediaReferenceError> { + return self.genericItem(key: .stickerPack(stickerPack: stickerPack), background: background, request: { next, error in return (updatedRemoteStickerPack(postbox: postbox, network: network, reference: stickerPack) |> mapError { _ -> RevalidateMediaReferenceError in return .generic @@ -677,8 +697,8 @@ final class MediaReferenceRevalidationContext { } } - func webPage(postbox: Postbox, network: Network, webPage: WebpageReference) -> Signal { - return self.genericItem(key: .webPage(webPage: webPage), request: { next, error in + func webPage(postbox: Postbox, network: Network, background: Bool, webPage: WebpageReference) -> Signal { + return self.genericItem(key: .webPage(webPage: webPage), background: background, request: { next, error in return (updatedRemoteWebpage(postbox: postbox, network: network, webPage: webPage) |> mapError { _ -> RevalidateMediaReferenceError in return .generic @@ -700,8 +720,8 @@ final class MediaReferenceRevalidationContext { } } - func savedGifs(postbox: Postbox, network: Network) -> Signal<[TelegramMediaFile], RevalidateMediaReferenceError> { - return self.genericItem(key: .savedGifs, request: { next, error in + func savedGifs(postbox: Postbox, network: Network, background: Bool) -> Signal<[TelegramMediaFile], RevalidateMediaReferenceError> { + return self.genericItem(key: .savedGifs, background: background, request: { next, error in let loadRecentGifs: Signal<[TelegramMediaFile], NoError> = postbox.transaction { transaction -> [TelegramMediaFile] in return transaction.getOrderedListItems(collectionId: Namespaces.OrderedItemList.CloudRecentGifs).compactMap({ item -> TelegramMediaFile? in if let contents = item.contents as? RecentMediaItem, let file = contents.media as? TelegramMediaFile { @@ -729,8 +749,8 @@ final class MediaReferenceRevalidationContext { } } - func peer(postbox: Postbox, network: Network, peer: PeerReference) -> Signal { - return self.genericItem(key: .peer(peer: peer), request: { next, error in + func peer(postbox: Postbox, network: Network, background: Bool, peer: PeerReference) -> Signal { + return self.genericItem(key: .peer(peer: peer), background: background, request: { next, error in return (updatedRemotePeer(postbox: postbox, network: network, peer: peer) |> mapError { _ -> RevalidateMediaReferenceError in return .generic @@ -748,8 +768,8 @@ final class MediaReferenceRevalidationContext { } } - func wallpapers(postbox: Postbox, network: Network) -> Signal<[TelegramWallpaper], RevalidateMediaReferenceError> { - return self.genericItem(key: .wallpapers, request: { next, error in + func wallpapers(postbox: Postbox, network: Network, background: Bool) -> Signal<[TelegramWallpaper], RevalidateMediaReferenceError> { + return self.genericItem(key: .wallpapers, background: background, request: { next, error in return (telegramWallpapers(postbox: postbox, network: network) |> last |> mapError { _ -> RevalidateMediaReferenceError in @@ -778,7 +798,7 @@ func revalidateMediaResourceReference(postbox: Postbox, network: Network, revali case let .media(media, _): switch media { case let .message(message, _): - return revalidationContext.message(postbox: postbox, network: network, message: message) + return revalidationContext.message(postbox: postbox, network: network, background: info.preferBackgroundReferenceRevalidation, message: message) |> mapToSignal { message -> Signal in for media in message.media { if let fileReference = findMediaResourceReference(media: media, resource: resource) { @@ -788,7 +808,7 @@ func revalidateMediaResourceReference(postbox: Postbox, network: Network, revali return .fail(.generic) } case let .stickerPack(stickerPack, media): - return revalidationContext.stickerPack(postbox: postbox, network: network, stickerPack: stickerPack) + return revalidationContext.stickerPack(postbox: postbox, network: network, background: info.preferBackgroundReferenceRevalidation, stickerPack: stickerPack) |> mapToSignal { result -> Signal in for item in result.1 { if let item = item as? StickerPackItem { @@ -802,7 +822,7 @@ func revalidateMediaResourceReference(postbox: Postbox, network: Network, revali return .fail(.generic) } case let .webPage(webPage, _): - return revalidationContext.webPage(postbox: postbox, network: network, webPage: webPage) + return revalidationContext.webPage(postbox: postbox, network: network, background: info.preferBackgroundReferenceRevalidation, webPage: webPage) |> mapToSignal { result -> Signal in if let fileReference = findMediaResourceReference(media: result, resource: resource) { return .single(fileReference) @@ -810,7 +830,7 @@ func revalidateMediaResourceReference(postbox: Postbox, network: Network, revali return .fail(.generic) } case let .savedGif(media): - return revalidationContext.savedGifs(postbox: postbox, network: network) + return revalidationContext.savedGifs(postbox: postbox, network: network, background: info.preferBackgroundReferenceRevalidation) |> mapToSignal { result -> Signal in for file in result { if media.id != nil && file.id == media.id { @@ -825,7 +845,7 @@ func revalidateMediaResourceReference(postbox: Postbox, network: Network, revali if let file = media as? TelegramMediaFile { for attribute in file.attributes { if case let .Sticker(sticker) = attribute, let stickerPack = sticker.packReference { - return revalidationContext.stickerPack(postbox: postbox, network: network, stickerPack: stickerPack) + return revalidationContext.stickerPack(postbox: postbox, network: network, background: info.preferBackgroundReferenceRevalidation, stickerPack: stickerPack) |> mapToSignal { result -> Signal in for item in result.1 { if let item = item as? StickerPackItem { @@ -844,7 +864,7 @@ func revalidateMediaResourceReference(postbox: Postbox, network: Network, revali return .fail(.generic) } case let .avatar(peer, _): - return revalidationContext.peer(postbox: postbox, network: network, peer: peer) + return revalidationContext.peer(postbox: postbox, network: network, background: info.preferBackgroundReferenceRevalidation, peer: peer) |> mapToSignal { updatedPeer -> Signal in for representation in updatedPeer.profileImageRepresentations { if representation.resource.id.isEqual(to: resource.id), let representationResource = representation.resource as? CloudFileMediaResource, let fileReference = representationResource.fileReference { @@ -854,7 +874,7 @@ func revalidateMediaResourceReference(postbox: Postbox, network: Network, revali return .fail(.generic) } case let .messageAuthorAvatar(message, _): - return revalidationContext.message(postbox: postbox, network: network, message: message) + return revalidationContext.message(postbox: postbox, network: network, background: info.preferBackgroundReferenceRevalidation, message: message) |> mapToSignal { updatedMessage -> Signal in if let author = updatedMessage.author { for representation in author.profileImageRepresentations { @@ -866,7 +886,7 @@ func revalidateMediaResourceReference(postbox: Postbox, network: Network, revali return .fail(.generic) } case .wallpaper: - return revalidationContext.wallpapers(postbox: postbox, network: network) + return revalidationContext.wallpapers(postbox: postbox, network: network, background: info.preferBackgroundReferenceRevalidation) |> mapToSignal { wallpapers -> Signal in for wallpaper in wallpapers { if case let .image(representations) = wallpaper { diff --git a/TelegramCore/ManagedSynchronizeSavedGifsOperations.swift b/TelegramCore/ManagedSynchronizeSavedGifsOperations.swift index 6c08117954..cd24082656 100644 --- a/TelegramCore/ManagedSynchronizeSavedGifsOperations.swift +++ b/TelegramCore/ManagedSynchronizeSavedGifsOperations.swift @@ -150,7 +150,7 @@ private func synchronizeSavedGifs(transaction: Transaction, postbox: Postbox, ne case .generic: return .fail(.generic) case .invalidReference: - return revalidateMediaResourceReference(postbox: postbox, network: network, revalidationContext: revalidationContext, info: TelegramCloudMediaResourceFetchInfo(reference: fileReference.resourceReference(fileReference.media.resource)), resource: fileReference.media.resource) + return revalidateMediaResourceReference(postbox: postbox, network: network, revalidationContext: revalidationContext, info: TelegramCloudMediaResourceFetchInfo(reference: fileReference.resourceReference(fileReference.media.resource), preferBackgroundReferenceRevalidation: false), resource: fileReference.media.resource) |> mapError { _ -> SaveGifError in return .generic } diff --git a/TelegramCore/ManagedSynchronizeSavedStickersOperations.swift b/TelegramCore/ManagedSynchronizeSavedStickersOperations.swift index 98137ba6e1..3ceb816cd8 100644 --- a/TelegramCore/ManagedSynchronizeSavedStickersOperations.swift +++ b/TelegramCore/ManagedSynchronizeSavedStickersOperations.swift @@ -150,7 +150,7 @@ private func synchronizeSavedStickers(transaction: Transaction, postbox: Postbox case .generic: return .fail(.generic) case .invalidReference: - return revalidateMediaResourceReference(postbox: postbox, network: network, revalidationContext: revalidationContext, info: TelegramCloudMediaResourceFetchInfo(reference: fileReference.resourceReference(fileReference.media.resource)), resource: fileReference.media.resource) + return revalidateMediaResourceReference(postbox: postbox, network: network, revalidationContext: revalidationContext, info: TelegramCloudMediaResourceFetchInfo(reference: fileReference.resourceReference(fileReference.media.resource), preferBackgroundReferenceRevalidation: false), resource: fileReference.media.resource) |> mapError { _ -> SaveStickerError in return .generic } diff --git a/TelegramCore/PendingMessageUploadedContent.swift b/TelegramCore/PendingMessageUploadedContent.swift index 3dca39ca3e..23cdd449f6 100644 --- a/TelegramCore/PendingMessageUploadedContent.swift +++ b/TelegramCore/PendingMessageUploadedContent.swift @@ -96,7 +96,7 @@ func mediaContentToUpload(network: Network, postbox: Postbox, auxiliaryMethods: } else { mediaReference = .savedGif(media: file) } - return revalidateMediaResourceReference(postbox: postbox, network: network, revalidationContext: revalidationContext, info: TelegramCloudMediaResourceFetchInfo(reference: mediaReference.resourceReference(file.resource)), resource: resource) + return revalidateMediaResourceReference(postbox: postbox, network: network, revalidationContext: revalidationContext, info: TelegramCloudMediaResourceFetchInfo(reference: mediaReference.resourceReference(file.resource), preferBackgroundReferenceRevalidation: false), resource: resource) |> mapError { _ -> PendingMessageUploadError in return .generic } diff --git a/TelegramCore/SearchMessages.swift b/TelegramCore/SearchMessages.swift index f111f1b783..0c958d6969 100644 --- a/TelegramCore/SearchMessages.swift +++ b/TelegramCore/SearchMessages.swift @@ -272,19 +272,19 @@ public func downloadMessage(postbox: Postbox, network: Network, messageId: Messa } } -func fetchRemoteMessage(postbox: Postbox, network: Network, message: MessageReference) -> Signal { +func fetchRemoteMessage(postbox: Postbox, source: FetchMessageHistoryHoleSource, message: MessageReference) -> Signal { guard case let .message(peer, id) = message.content else { return .single(nil) } let signal: Signal if id.peerId.namespace == Namespaces.Peer.CloudChannel { if let channel = peer.inputChannel { - signal = network.request(Api.functions.channels.getMessages(channel: channel, id: [Api.InputMessage.inputMessageID(id: id.id)])) + signal = source.request(Api.functions.channels.getMessages(channel: channel, id: [Api.InputMessage.inputMessageID(id: id.id)])) } else { signal = .fail(MTRpcError(errorCode: 400, errorDescription: "Peer Not Found")) } } else if id.peerId.namespace == Namespaces.Peer.CloudUser || id.peerId.namespace == Namespaces.Peer.CloudGroup { - signal = network.request(Api.functions.messages.getMessages(id: [Api.InputMessage.inputMessageID(id: id.id)])) + signal = source.request(Api.functions.messages.getMessages(id: [Api.InputMessage.inputMessageID(id: id.id)])) } else { signal = .fail(MTRpcError(errorCode: 400, errorDescription: "Invalid Peer")) }