Skip to content

Commit

Permalink
Cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
kean committed May 6, 2021
1 parent 23ef6f8 commit 3548c01
Show file tree
Hide file tree
Showing 10 changed files with 171 additions and 121 deletions.
17 changes: 4 additions & 13 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:

jobs:
ios-latest:
name: Unit Tests (iOS 14.2, Xcode 12.2)
name: Unit Tests (iOS 14.2, Xcode 12.4)
runs-on: macOS-latest
env:
DEVELOPER_DIR: /Applications/Xcode_12.2.app/Contents/Developer
Expand All @@ -19,7 +19,7 @@ jobs:
- name: Run Tests
run: Scripts/test.sh -d "OS=14.2,name=iPhone 11"
macos-latest:
name: Unit Tests (macOS, Xcode 12.2)
name: Unit Tests (macOS, Xcode 12.4)
runs-on: macOS-latest
env:
DEVELOPER_DIR: /Applications/Xcode_12.2.app/Contents/Developer
Expand All @@ -28,7 +28,7 @@ jobs:
- name: Run Tests
run: Scripts/test.sh -d "arch=x86_64"
tvos-latest:
name: Unit Tests (tvOS 14.2, Xcode 12.2)
name: Unit Tests (tvOS 14.2, Xcode 12.4)
runs-on: macOS-latest
env:
DEVELOPER_DIR: /Applications/Xcode_12.2.app/Contents/Developer
Expand All @@ -37,7 +37,7 @@ jobs:
- name: Run Tests
run: Scripts/test.sh -d "OS=14.2,name=Apple TV 4K"
watchos-latest:
name: Build (watchOS 7.1, Xcode 12.2)
name: Build (watchOS 7.1, Xcode 12.4)
runs-on: macOS-latest
env:
DEVELOPER_DIR: /Applications/Xcode_12.2.app/Contents/Developer
Expand All @@ -54,15 +54,6 @@ jobs:
- uses: actions/checkout@v2
- name: Run Tests
run: Scripts/test.sh -d "OS=14.0,name=iPhone 11"
ios-xcode-11_2_1:
name: Unit Tests (iOS 13.2.2, Xcode 11.2.1)
runs-on: macOS-latest
env:
DEVELOPER_DIR: /Applications/Xcode_11.2.1.app/Contents/Developer
steps:
- uses: actions/checkout@v2
- name: Run Tests
run: Scripts/test.sh -d "OS=13.2.2,name=iPhone 11"
ios-thread-safety:
name: Thread Safety Tests (TSan Enabled)
runs-on: macOS-latest
Expand Down
26 changes: 13 additions & 13 deletions Nuke.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -116,16 +116,16 @@
0C91B0F82438E84E007F9100 /* fixture-tiny.jpeg in Resources */ = {isa = PBXBuildFile; fileRef = 0C91B0F72438E84E007F9100 /* fixture-tiny.jpeg */; };
0C95FD542571B278008D4FC2 /* baseline.webp in Resources */ = {isa = PBXBuildFile; fileRef = 0C95FD532571B278008D4FC2 /* baseline.webp */; };
0C973E141D9FDB9F00C00AD9 /* Nuke.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0C9174901BAE99EE004A7905 /* Nuke.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
0C9B6E7620B9F3E2001924B8 /* ImagePipelineDeduplicationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C9B6E7520B9F3E2001924B8 /* ImagePipelineDeduplicationTests.swift */; };
0C9B6E7620B9F3E2001924B8 /* ImagePipelineCoalescingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C9B6E7520B9F3E2001924B8 /* ImagePipelineCoalescingTests.swift */; };
0CA5D954263CCEA500E08E17 /* ImagePublisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CA5D953263CCEA500E08E17 /* ImagePublisher.swift */; };
0CAAB0101E45D6DA00924450 /* NukeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CAAB00F1E45D6DA00924450 /* NukeExtensions.swift */; };
0CAAB0131E45D6DA00924450 /* NukeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CAAB00F1E45D6DA00924450 /* NukeExtensions.swift */; };
0CB26802208F2565004C83F4 /* DataCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CB26801208F2565004C83F4 /* DataCache.swift */; };
0CB26807208F25C2004C83F4 /* DataCacheTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CB26806208F25C2004C83F4 /* DataCacheTests.swift */; };
0CB2EFD22110F38600F7C63F /* ImagePipelineConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CB2EFD12110F38600F7C63F /* ImagePipelineConfigurationTests.swift */; };
0CB2EFD62110F52C00F7C63F /* RateLimiterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CB2EFD52110F52C00F7C63F /* RateLimiterTests.swift */; };
0CB402D525B6569700F5A241 /* TaskLoadImageData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CB402D425B6569700F5A241 /* TaskLoadImageData.swift */; };
0CB402DB25B656D200F5A241 /* TaskLoadDecodedImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CB402DA25B656D200F5A241 /* TaskLoadDecodedImage.swift */; };
0CB402D525B6569700F5A241 /* TaskFetchOriginalImageData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CB402D425B6569700F5A241 /* TaskFetchOriginalImageData.swift */; };
0CB402DB25B656D200F5A241 /* TaskFetchDecodedImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CB402DA25B656D200F5A241 /* TaskFetchDecodedImage.swift */; };
0CB4030125B6639200F5A241 /* TaskLoadImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CB4030025B6639200F5A241 /* TaskLoadImage.swift */; };
0CC36A1225B8BC0800811018 /* Allocations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CC36A1125B8BC0800811018 /* Allocations.swift */; };
0CC36A1925B8BC2500811018 /* RateLimiter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CC36A1825B8BC2500811018 /* RateLimiter.swift */; };
Expand Down Expand Up @@ -280,16 +280,16 @@
0C91B0F72438E84E007F9100 /* fixture-tiny.jpeg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "fixture-tiny.jpeg"; sourceTree = "<group>"; };
0C94466D1D47EC0E006DB314 /* ImageViewTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageViewTests.swift; sourceTree = "<group>"; };
0C95FD532571B278008D4FC2 /* baseline.webp */ = {isa = PBXFileReference; lastKnownFileType = file; path = baseline.webp; sourceTree = "<group>"; };
0C9B6E7520B9F3E2001924B8 /* ImagePipelineDeduplicationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagePipelineDeduplicationTests.swift; sourceTree = "<group>"; };
0C9B6E7520B9F3E2001924B8 /* ImagePipelineCoalescingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagePipelineCoalescingTests.swift; sourceTree = "<group>"; };
0CA5D953263CCEA500E08E17 /* ImagePublisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagePublisher.swift; sourceTree = "<group>"; };
0CA82BDC237AE09F00338375 /* install_swiftlint.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = install_swiftlint.sh; path = Scripts/install_swiftlint.sh; sourceTree = "<group>"; };
0CAAB00F1E45D6DA00924450 /* NukeExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NukeExtensions.swift; sourceTree = "<group>"; };
0CB26801208F2565004C83F4 /* DataCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataCache.swift; sourceTree = "<group>"; };
0CB26806208F25C2004C83F4 /* DataCacheTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataCacheTests.swift; sourceTree = "<group>"; };
0CB2EFD12110F38600F7C63F /* ImagePipelineConfigurationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagePipelineConfigurationTests.swift; sourceTree = "<group>"; };
0CB2EFD52110F52C00F7C63F /* RateLimiterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RateLimiterTests.swift; sourceTree = "<group>"; };
0CB402D425B6569700F5A241 /* TaskLoadImageData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskLoadImageData.swift; sourceTree = "<group>"; };
0CB402DA25B656D200F5A241 /* TaskLoadDecodedImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskLoadDecodedImage.swift; sourceTree = "<group>"; };
0CB402D425B6569700F5A241 /* TaskFetchOriginalImageData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskFetchOriginalImageData.swift; sourceTree = "<group>"; };
0CB402DA25B656D200F5A241 /* TaskFetchDecodedImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskFetchDecodedImage.swift; sourceTree = "<group>"; };
0CB4030025B6639200F5A241 /* TaskLoadImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskLoadImage.swift; sourceTree = "<group>"; };
0CC36A1125B8BC0800811018 /* Allocations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Allocations.swift; sourceTree = "<group>"; };
0CC36A1825B8BC2500811018 /* RateLimiter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RateLimiter.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -573,7 +573,7 @@
children = (
0CE3992C1D4697CE00A87D47 /* ImagePipelineTests.swift */,
0CC6271425BDF7A100466F04 /* ImagePipelineMemoryCacheTests.swift */,
0C9B6E7520B9F3E2001924B8 /* ImagePipelineDeduplicationTests.swift */,
0C9B6E7520B9F3E2001924B8 /* ImagePipelineCoalescingTests.swift */,
0CB2EFD12110F38600F7C63F /* ImagePipelineConfigurationTests.swift */,
0C2A8CF620970B790013FD65 /* ImagePipelineResumableDataTests.swift */,
0C2A8CFA20970D8D0013FD65 /* ImagePipelineProgressiveDecodingTests.swift */,
Expand Down Expand Up @@ -621,10 +621,10 @@
0C505B6B2286F3AD006D5399 /* Task.swift */,
0C2CD6EA25B67FB30017018F /* ImagePipelineTask.swift */,
0CB4030025B6639200F5A241 /* TaskLoadImage.swift */,
0CB402DA25B656D200F5A241 /* TaskLoadDecodedImage.swift */,
0CB402D425B6569700F5A241 /* TaskLoadImageData.swift */,
0C9165E526431942006B1D4F /* OperationTask.swift */,
0C2A368A26437BF100F1D000 /* TaskLoadData.swift */,
0CB402DA25B656D200F5A241 /* TaskFetchDecodedImage.swift */,
0CB402D425B6569700F5A241 /* TaskFetchOriginalImageData.swift */,
0C9165E526431942006B1D4F /* OperationTask.swift */,
);
path = Tasks;
sourceTree = "<group>";
Expand Down Expand Up @@ -1043,7 +1043,7 @@
0C91B0F42438E38B007F9100 /* CompositionTests.swift in Sources */,
0C91B0F62438E3CB007F9100 /* GaussianBlurTests.swift in Sources */,
0C6D0A8820E574400037B68F /* MockDataCache.swift in Sources */,
0C9B6E7620B9F3E2001924B8 /* ImagePipelineDeduplicationTests.swift in Sources */,
0C9B6E7620B9F3E2001924B8 /* ImagePipelineCoalescingTests.swift in Sources */,
0C91B0F22438E374007F9100 /* AnonymousTests.swift in Sources */,
0CE3992D1D4697CE00A87D47 /* ImagePipelineTests.swift in Sources */,
0C64F73B24383043001983C6 /* ImageEncoderTests.swift in Sources */,
Expand Down Expand Up @@ -1104,7 +1104,7 @@
0C78A2A7263F4E680051E0FF /* ImagePipelineCache.swift in Sources */,
0C53C8B1263C968200E62D03 /* ImagePipelineDelegate.swift in Sources */,
0C9165E626431942006B1D4F /* OperationTask.swift in Sources */,
0CB402DB25B656D200F5A241 /* TaskLoadDecodedImage.swift in Sources */,
0CB402DB25B656D200F5A241 /* TaskFetchDecodedImage.swift in Sources */,
0CC36A3325B8BC7900811018 /* ResumableData.swift in Sources */,
0C0FD61C1CA47FE1002A78FB /* ImageViewExtensions.swift in Sources */,
0CB26802208F2565004C83F4 /* DataCache.swift in Sources */,
Expand All @@ -1117,7 +1117,7 @@
0C42D4C722A286260094CB5A /* Deprecated.swift in Sources */,
0CE2D9BA2084FDDD00934B28 /* ImageDecoding.swift in Sources */,
0CC36A1925B8BC2500811018 /* RateLimiter.swift in Sources */,
0CB402D525B6569700F5A241 /* TaskLoadImageData.swift in Sources */,
0CB402D525B6569700F5A241 /* TaskFetchOriginalImageData.swift in Sources */,
0C2CD6EB25B67FB30017018F /* ImagePipelineTask.swift in Sources */,
0CF4DE7D1D412A9E00170289 /* ImagePrefetcher.swift in Sources */,
);
Expand Down
60 changes: 35 additions & 25 deletions Sources/ImagePipeline.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ public /* final */ class ImagePipeline {

private var tasks = [ImageTask: TaskSubscription]()

private let loadDataTasks: TaskPool<ImageRequest.LoadKeyForProcessedImage, (Data, URLResponse?), Error>
private let decompressedImageTasks: TaskPool<ImageRequest.LoadKeyForProcessedImage, ImageResponse, Error>
private let originalImageTasks: TaskPool<ImageRequest.LoadKeyForOriginalImage, ImageResponse, Error>
private let originalImageDataTasks: TaskPool<ImageRequest.LoadKeyForOriginalImage, (Data, URLResponse?), Error>
private let imageProcessingTasks: TaskPool<ImageProcessingKey, ImageResponse, Swift.Error>
private let tasksLoadData: TaskPool<ImageRequest.LoadKeyForProcessedImage, (Data, URLResponse?), Error>
private let tasksLoadImage: TaskPool<ImageRequest.LoadKeyForProcessedImage, ImageResponse, Error>
private let tasksFetchDecodedImage: TaskPool<ImageRequest.LoadKeyForOriginalImage, ImageResponse, Error>
private let tasksFetchOriginalImageData: TaskPool<ImageRequest.LoadKeyForOriginalImage, (Data, URLResponse?), Error>
private let tasksProcessImage: TaskPool<ImageProcessingKey, ImageResponse, Swift.Error>

// The queue on which the entire subsystem is synchronized.
let queue = DispatchQueue(label: "com.github.kean.Nuke.ImagePipeline", qos: .userInitiated)
Expand Down Expand Up @@ -63,11 +63,11 @@ public /* final */ class ImagePipeline {
self.delegate = configuration.delegate ?? ImagePipelineDefaultDelegate()

let isDeduplicationEnabled = configuration.isDeduplicationEnabled
self.loadDataTasks = TaskPool(isDeduplicationEnabled)
self.decompressedImageTasks = TaskPool(isDeduplicationEnabled)
self.originalImageTasks = TaskPool(isDeduplicationEnabled)
self.originalImageDataTasks = TaskPool(isDeduplicationEnabled)
self.imageProcessingTasks = TaskPool(isDeduplicationEnabled)
self.tasksLoadData = TaskPool(isDeduplicationEnabled)
self.tasksLoadImage = TaskPool(isDeduplicationEnabled)
self.tasksFetchDecodedImage = TaskPool(isDeduplicationEnabled)
self.tasksFetchOriginalImageData = TaskPool(isDeduplicationEnabled)
self.tasksProcessImage = TaskPool(isDeduplicationEnabled)

self._nextTaskId = UnsafeMutablePointer<Int64>.allocate(capacity: 1)
self._nextTaskId.initialize(to: 0)
Expand Down Expand Up @@ -322,42 +322,52 @@ private extension ImagePipeline {

// MARK: - Task Factory (Private)

// When you request an image, the pipeline creates the following dependency graph:
// When you request an image or image data, the pipeline creates a graph of tasks
// (some tasks are added to the graph on demand).
//
// TaskLoadImage+ -> TaskLoadDecodedImage -> TaskLoadImageData
// `loadImage()` call is represented by TaskLoadImage:
//
// Each task represents a resource to be retrieved - processed image, original image, etc.
// Each task can be reuse of the same resource requested multiple times.

// TaskLoadImage+ -> TaskFetchDecodedImage -> TaskFetchOriginalImageData
// -> TaskProcessImage
//
// `loadData()` call is represented by TaskLoadData:
//
// TaskLoadData -> TaskFetchOriginalImageData
//
//
// Each task represents a resource or a piece of work required to produce the
// final result. The pipeline reduces the amount of duplicated work by coalescing
// the tasks that represent the same work. For example, if you all `loadImage()`
// and `loadData()` with the same request, only on `TaskFetchOriginalImageData`
// is created. The work is split between tasks to minimize any duplicated work.
extension ImagePipeline {
func makeTaskLoadImage(for request: ImageRequest) -> Task<ImageResponse, Error>.Publisher {
decompressedImageTasks.publisherForKey(request.makeLoadKeyForProcessedImage()) {
tasksLoadImage.publisherForKey(request.makeLoadKeyForProcessedImage()) {
TaskLoadImage(self, request)
}
}

#warning("correct key?")
func makeTaskLoadData(for request: ImageRequest) -> Task<(Data, URLResponse?), Error>.Publisher {
loadDataTasks.publisherForKey(request.makeLoadKeyForProcessedImage()) {
tasksLoadData.publisherForKey(request.makeLoadKeyForProcessedImage()) {
TaskLoadData(self, request)
}
}

func makeTaskProcessImage(key: ImageProcessingKey, process: @escaping () -> ImageResponse?) -> Task<ImageResponse, Swift.Error>.Publisher {
imageProcessingTasks.publisherForKey(key) {
tasksProcessImage.publisherForKey(key) {
OperationTask(self, configuration.imageProcessingQueue, process)
}
}

func makeTaskDecodeImage(for request: ImageRequest) -> Task<ImageResponse, Error>.Publisher {
originalImageTasks.publisherForKey(request.makeLoadKeyForOriginalImage()) {
TaskLoadDecodedImage(self, request)
func makeTaskFetchDecodedImage(for request: ImageRequest) -> Task<ImageResponse, Error>.Publisher {
tasksFetchDecodedImage.publisherForKey(request.makeLoadKeyForOriginalImage()) {
TaskFetchDecodedImage(self, request)
}
}

func makeTaskLoadImageData(for request: ImageRequest) -> Task<(Data, URLResponse?), Error>.Publisher {
originalImageDataTasks.publisherForKey(request.makeLoadKeyForOriginalImage()) {
TaskLoadImageData(self, request)
func makeTaskFetchOriginalImageData(for request: ImageRequest) -> Task<(Data, URLResponse?), Error>.Publisher {
tasksFetchOriginalImageData.publisherForKey(request.makeLoadKeyForOriginalImage()) {
TaskFetchOriginalImageData(self, request)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
import Foundation

/// Receives data from ``TaskLoadImageData` and decodes it as it arrives.
final class TaskLoadDecodedImage: ImagePipelineTask<ImageResponse> {
final class TaskFetchDecodedImage: ImagePipelineTask<ImageResponse> {
private var decoder: ImageDecoding?

override func start() {
dependency = pipeline.makeTaskLoadImageData(for: request).subscribe(self) { [weak self] in
dependency = pipeline.makeTaskFetchOriginalImageData(for: request).subscribe(self) { [weak self] in
self?.didReceiveData($0.0, urlResponse: $0.1, isCompleted: $1)
}
}
Expand Down
Loading

0 comments on commit 3548c01

Please sign in to comment.