mirror of
https://github.com/immich-app/immich.git
synced 2026-04-06 09:12:03 -04:00
refactor(mobile): IOS replace DispatchQueue + DispatchSemaphore with OperationQueue for image processing (#27471)
refactor: replace DispatchQueue + DispatchSemaphore with OperationQueue for image processing
This commit is contained in:
parent
196307bca5
commit
6fcf651d76
@ -1,7 +1,12 @@
|
||||
import Foundation
|
||||
|
||||
enum ImageProcessing {
|
||||
static let queue = DispatchQueue(label: "thumbnail.processing", qos: .userInitiated, attributes: .concurrent)
|
||||
static let semaphore = DispatchSemaphore(value: ProcessInfo.processInfo.activeProcessorCount * 2)
|
||||
static let queue = {
|
||||
let q = OperationQueue()
|
||||
q.name = "thumbnail.processing"
|
||||
q.qualityOfService = .userInitiated
|
||||
q.maxConcurrentOperationCount = ProcessInfo.processInfo.activeProcessorCount * 2
|
||||
return q
|
||||
}()
|
||||
static let cancelledResult = Result<[String: Int64]?, any Error>.success(nil)
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ import MobileCoreServices
|
||||
import Photos
|
||||
|
||||
class LocalImageRequest {
|
||||
weak var workItem: DispatchWorkItem?
|
||||
weak var operation: Operation?
|
||||
var isCancelled = false
|
||||
let callback: (Result<[String: Int64]?, any Error>) -> Void
|
||||
|
||||
@ -50,7 +50,7 @@ class LocalImageApiImpl: LocalImageApi {
|
||||
}()
|
||||
|
||||
func getThumbhash(thumbhash: String, completion: @escaping (Result<[String : Int64], any Error>) -> Void) {
|
||||
ImageProcessing.queue.async {
|
||||
ImageProcessing.queue.addOperation {
|
||||
guard let data = Data(base64Encoded: thumbhash)
|
||||
else { return completion(.failure(PigeonError(code: "", message: "Invalid base64 string: \(thumbhash)", details: nil)))}
|
||||
|
||||
@ -66,16 +66,7 @@ class LocalImageApiImpl: LocalImageApi {
|
||||
|
||||
func requestImage(assetId: String, requestId: Int64, width: Int64, height: Int64, isVideo: Bool, preferEncoded: Bool, completion: @escaping (Result<[String: Int64]?, any Error>) -> Void) {
|
||||
let request = LocalImageRequest(callback: completion)
|
||||
let item = DispatchWorkItem {
|
||||
if request.isCancelled {
|
||||
return completion(ImageProcessing.cancelledResult)
|
||||
}
|
||||
|
||||
ImageProcessing.semaphore.wait()
|
||||
defer {
|
||||
ImageProcessing.semaphore.signal()
|
||||
}
|
||||
|
||||
let operation = BlockOperation {
|
||||
if request.isCancelled {
|
||||
return completion(ImageProcessing.cancelledResult)
|
||||
}
|
||||
@ -180,9 +171,9 @@ class LocalImageApiImpl: LocalImageApi {
|
||||
}
|
||||
}
|
||||
|
||||
request.workItem = item
|
||||
request.operation = operation
|
||||
Self.add(requestId: requestId, request: request)
|
||||
ImageProcessing.queue.async(execute: item)
|
||||
ImageProcessing.queue.addOperation(operation)
|
||||
}
|
||||
|
||||
func cancelRequest(requestId: Int64) {
|
||||
@ -201,8 +192,8 @@ class LocalImageApiImpl: LocalImageApi {
|
||||
requestQueue.async {
|
||||
guard let request = requests.removeValue(forKey: requestId) else { return }
|
||||
request.isCancelled = true
|
||||
guard let item = request.workItem else { return }
|
||||
if item.isCancelled {
|
||||
guard let operation = request.operation else { return }
|
||||
if operation.isCancelled {
|
||||
cancelQueue.async { request.callback(ImageProcessing.cancelledResult) }
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,10 +73,7 @@ class RemoteImageApiImpl: NSObject, RemoteImageApi {
|
||||
return request.completion(.failure(PigeonError(code: "", message: "No data received", details: nil)))
|
||||
}
|
||||
|
||||
ImageProcessing.queue.async {
|
||||
ImageProcessing.semaphore.wait()
|
||||
defer { ImageProcessing.semaphore.signal() }
|
||||
|
||||
ImageProcessing.queue.addOperation {
|
||||
if request.isCancelled {
|
||||
return request.completion(ImageProcessing.cancelledResult)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user