Skip to content

Commit e6088e7

Browse files
Refactors for simplicity
1 parent 95be150 commit e6088e7

File tree

3 files changed

+62
-67
lines changed

3 files changed

+62
-67
lines changed

Sources/DataLoader/DataLoader.swift

Lines changed: 41 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ final public class DataLoader<Key: Hashable, Value> {
2121
private let batchLoadFunction: BatchLoadFunction<Key, Value>
2222
private let options: DataLoaderOptions<Key, Value>
2323

24-
private var futureCache = [Key: EventLoopFuture<Value>]()
24+
private var cache = [Key: EventLoopFuture<Value>]()
2525
private var queue = LoaderQueue<Key, Value>()
2626

2727
public init(options: DataLoaderOptions<Key, Value> = DataLoaderOptions(), batchLoadFunction: @escaping BatchLoadFunction<Key, Value>) {
@@ -30,14 +30,14 @@ final public class DataLoader<Key: Hashable, Value> {
3030
}
3131

3232
/// Loads a key, returning an `EventLoopFuture` for the value represented by that key.
33-
public func load(key: Key, on eventLoop: EventLoopGroup) throws -> EventLoopFuture<Value> {
33+
public func load(key: Key, on eventLoopGroup: EventLoopGroup) throws -> EventLoopFuture<Value> {
3434
let cacheKey = options.cacheKeyFunction?(key) ?? key
3535

36-
if options.cachingEnabled, let cachedFuture = futureCache[cacheKey] {
36+
if options.cachingEnabled, let cachedFuture = cache[cacheKey] {
3737
return cachedFuture
3838
}
3939

40-
let promise: EventLoopPromise<Value> = eventLoop.next().makePromise()
40+
let promise: EventLoopPromise<Value> = eventLoopGroup.next().makePromise()
4141

4242
if options.batchingEnabled {
4343
queue.append((key: key, promise: promise))
@@ -58,7 +58,7 @@ final public class DataLoader<Key: Hashable, Value> {
5858
let future = promise.futureResult
5959

6060
if options.cachingEnabled {
61-
futureCache[cacheKey] = future
61+
cache[cacheKey] = future
6262
}
6363

6464
return future
@@ -78,14 +78,16 @@ final public class DataLoader<Key: Hashable, Value> {
7878
/// myLoader.load(key: "b", on: eventLoopGroup)
7979
/// ].flatten(on: eventLoopGroup).wait()
8080
/// ```
81-
public func loadMany(keys: [Key], on eventLoop: EventLoopGroup) throws -> EventLoopFuture<[Value]> {
82-
guard !keys.isEmpty else { return eventLoop.next().makeSucceededFuture([]) }
81+
public func loadMany(keys: [Key], on eventLoopGroup: EventLoopGroup) throws -> EventLoopFuture<[Value]> {
82+
guard !keys.isEmpty else {
83+
return eventLoopGroup.next().makeSucceededFuture([])
84+
}
8385

84-
let promise: EventLoopPromise<[Value]> = eventLoop.next().makePromise()
86+
let promise: EventLoopPromise<[Value]> = eventLoopGroup.next().makePromise()
8587

8688
var result = [Value]()
8789

88-
let futures = try keys.map { try load(key: $0, on: eventLoop) }
90+
let futures = try keys.map { try load(key: $0, on: eventLoopGroup) }
8991

9092
for future in futures {
9193
_ = future.map { value in
@@ -105,7 +107,7 @@ final public class DataLoader<Key: Hashable, Value> {
105107
@discardableResult
106108
func clear(key: Key) -> DataLoader<Key, Value> {
107109
let cacheKey = options.cacheKeyFunction?(key) ?? key
108-
futureCache.removeValue(forKey: cacheKey)
110+
cache.removeValue(forKey: cacheKey)
109111
return self
110112
}
111113

@@ -114,7 +116,7 @@ final public class DataLoader<Key: Hashable, Value> {
114116
/// method chaining.
115117
@discardableResult
116118
func clearAll() -> DataLoader<Key, Value> {
117-
futureCache.removeAll()
119+
cache.removeAll()
118120
return self
119121
}
120122

@@ -124,66 +126,67 @@ final public class DataLoader<Key: Hashable, Value> {
124126
func prime(key: Key, value: Value, on eventLoop: EventLoopGroup) -> DataLoader<Key, Value> {
125127
let cacheKey = options.cacheKeyFunction?(key) ?? key
126128

127-
if futureCache[cacheKey] == nil {
129+
if cache[cacheKey] == nil {
128130
let promise: EventLoopPromise<Value> = eventLoop.next().makePromise()
129131
promise.succeed(value)
130132

131-
futureCache[cacheKey] = promise.futureResult
133+
cache[cacheKey] = promise.futureResult
132134
}
133135

134136
return self
135137
}
136138

137-
public func dispatchQueue(on eventLoop: EventLoopGroup) throws {
139+
/// Executes the queue of keys, completing the `EventLoopFutures`.
140+
///
141+
/// The client must run this manually to compete the `EventLoopFutures` of the keys.
142+
public func execute() throws {
138143
// Take the current loader queue, replacing it with an empty queue.
139-
let queue = self.queue
144+
let batch = self.queue
140145
self.queue = []
141146

142147
// If a maxBatchSize was provided and the queue is longer, then segment the
143148
// queue into multiple batches, otherwise treat the queue as a single batch.
144-
if let maxBatchSize = options.maxBatchSize, maxBatchSize > 0 && maxBatchSize < queue.count {
145-
for i in 0...(queue.count / maxBatchSize) {
149+
if let maxBatchSize = options.maxBatchSize, maxBatchSize > 0 && maxBatchSize < batch.count {
150+
for i in 0...(batch.count / maxBatchSize) {
146151
let startIndex = i * maxBatchSize
147152
let endIndex = (i + 1) * maxBatchSize
148-
let slicedQueue = queue[startIndex..<min(endIndex, queue.count)]
149-
try dispatchQueueBatch(queue: Array(slicedQueue), on: eventLoop)
153+
let slicedBatch = batch[startIndex..<min(endIndex, batch.count)]
154+
try executeBatch(batch: Array(slicedBatch))
150155
}
151156
} else {
152-
try dispatchQueueBatch(queue: queue, on: eventLoop)
157+
try executeBatch(batch: batch)
153158
}
154159
}
155160

156-
private func dispatchQueueBatch(queue: LoaderQueue<Key, Value>, on eventLoop: EventLoopGroup) throws {
157-
let keys = queue.map { $0.key }
161+
private func executeBatch(batch: LoaderQueue<Key, Value>) throws {
162+
let keys = batch.map { $0.key }
158163

159164
if keys.isEmpty {
160165
return
161166
}
162167

163168
// Step through the values, resolving or rejecting each Promise in the
164169
// loaded queue.
165-
_ = try batchLoadFunction(keys)
166-
.flatMapThrowing { values in
167-
if values.count != keys.count {
168-
throw DataLoaderError.typeError("The function did not return an array of the same length as the array of keys. \nKeys count: \(keys.count)\nValues count: \(values.count)")
169-
}
170+
_ = try batchLoadFunction(keys).flatMapThrowing { values in
171+
if values.count != keys.count {
172+
throw DataLoaderError.typeError("The function did not return an array of the same length as the array of keys. \nKeys count: \(keys.count)\nValues count: \(values.count)")
173+
}
170174

171-
for entry in queue.enumerated() {
172-
let result = values[entry.offset]
175+
for entry in batch.enumerated() {
176+
let result = values[entry.offset]
173177

174-
switch result {
175-
case .failure(let error): entry.element.promise.fail(error)
176-
case .success(let value): entry.element.promise.succeed(value)
177-
}
178-
}
178+
switch result {
179+
case .failure(let error): entry.element.promise.fail(error)
180+
case .success(let value): entry.element.promise.succeed(value)
179181
}
180-
.recover { error in
181-
self.failedDispatch(queue: queue, error: error)
182+
}
183+
}.recover { error in
184+
self.failedDispatch(batch: batch, error: error)
182185
}
183186
}
184187

185-
private func failedDispatch(queue: LoaderQueue<Key, Value>, error: Error) {
186-
queue.forEach { (key, promise) in
188+
private func failedDispatch(batch: LoaderQueue<Key, Value>, error: Error) {
189+
for (key, promise) in batch {
187190
_ = clear(key: key)
188191
promise.fail(error)
189192
}

Tests/DataLoaderTests/DataLoaderAbuseTests.swift

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class DataLoaderAbuseTests: XCTestCase {
1818

1919
let value = try identityLoader.load(key: 1, on: eventLoopGroup)
2020

21-
XCTAssertNoThrow(try identityLoader.dispatchQueue(on: eventLoopGroup))
21+
XCTAssertNoThrow(try identityLoader.execute())
2222

2323
XCTAssertThrowsError(try value.wait(), "Did not return value for key: 1")
2424
}
@@ -35,7 +35,7 @@ class DataLoaderAbuseTests: XCTestCase {
3535

3636
let value = try identityLoader.load(key: 1, on: eventLoopGroup)
3737

38-
XCTAssertNoThrow(try identityLoader.dispatchQueue(on: eventLoopGroup))
38+
XCTAssertNoThrow(try identityLoader.execute())
3939

4040
XCTAssertThrowsError(try value.wait(), "The function did not return an array of the same length as the array of keys. \nKeys count: 1\nValues count: 0")
4141
}
@@ -63,7 +63,7 @@ class DataLoaderAbuseTests: XCTestCase {
6363
let value1 = try identityLoader.load(key: 1, on: eventLoopGroup)
6464
let value2 = try identityLoader.load(key: 2, on: eventLoopGroup)
6565

66-
XCTAssertNoThrow(try identityLoader.dispatchQueue(on: eventLoopGroup))
66+
XCTAssertNoThrow(try identityLoader.execute())
6767

6868
XCTAssertThrowsError(try value2.wait())
6969

@@ -93,20 +93,12 @@ class DataLoaderAbuseTests: XCTestCase {
9393
let value1 = try identityLoader.load(key: 1, on: eventLoopGroup)
9494
let value2 = try identityLoader.load(key: 2, on: eventLoopGroup)
9595

96-
XCTAssertNoThrow(try identityLoader.dispatchQueue(on: eventLoopGroup))
96+
XCTAssertNoThrow(try identityLoader.execute())
9797

9898
XCTAssertThrowsError(try value2.wait())
9999

100100
XCTAssertTrue(try value1.wait() == 1)
101101
}
102-
103-
static var allTests: [(String, (DataLoaderAbuseTests) -> () throws -> Void)] = [
104-
("testFuntionWithNoValues", testFuntionWithNoValues),
105-
("testBatchFuntionMustPromiseAnArrayOfCorrectLength", testBatchFuntionMustPromiseAnArrayOfCorrectLength),
106-
("testBatchFuntionWithSomeValues", testBatchFuntionWithSomeValues),
107-
("testFuntionWithSomeValues", testFuntionWithSomeValues)
108-
]
109-
110102
}
111103

112104
extension String: Error { }

Tests/DataLoaderTests/DataLoaderTests.swift

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ final class DataLoaderTests: XCTestCase {
2121

2222
let value = try identityLoader.load(key: 1, on: eventLoopGroup)
2323

24-
XCTAssertNoThrow(try identityLoader.dispatchQueue(on: eventLoopGroup))
24+
XCTAssertNoThrow(try identityLoader.execute())
2525

2626
XCTAssertTrue(try value.wait() == 1)
2727
}
@@ -41,7 +41,7 @@ final class DataLoaderTests: XCTestCase {
4141

4242
let values = try identityLoader.loadMany(keys: [1, 2], on: eventLoopGroup)
4343

44-
XCTAssertNoThrow(try identityLoader.dispatchQueue(on: eventLoopGroup))
44+
XCTAssertNoThrow(try identityLoader.execute())
4545

4646
XCTAssertTrue(try values.wait() == [1,2])
4747

@@ -69,7 +69,7 @@ final class DataLoaderTests: XCTestCase {
6969
let value1 = try identityLoader.load(key: 1, on: eventLoopGroup)
7070
let value2 = try identityLoader.load(key: 2, on: eventLoopGroup)
7171

72-
XCTAssertNoThrow(try identityLoader.dispatchQueue(on: eventLoopGroup))
72+
XCTAssertNoThrow(try identityLoader.execute())
7373

7474
XCTAssertTrue(try value1.map { $0 }.wait() == 1)
7575
XCTAssertTrue(try value2.map { $0 }.wait() == 2)
@@ -97,7 +97,7 @@ final class DataLoaderTests: XCTestCase {
9797
let value2 = try identityLoader.load(key: 2, on: eventLoopGroup)
9898
let value3 = try identityLoader.load(key: 3, on: eventLoopGroup)
9999

100-
XCTAssertNoThrow(try identityLoader.dispatchQueue(on: eventLoopGroup))
100+
XCTAssertNoThrow(try identityLoader.execute())
101101

102102
XCTAssertTrue(try value1.map { $0 }.wait() == 1)
103103
XCTAssertTrue(try value2.map { $0 }.wait() == 2)
@@ -125,7 +125,7 @@ final class DataLoaderTests: XCTestCase {
125125
let value1 = try identityLoader.load(key: 1, on: eventLoopGroup)
126126
let value2 = try identityLoader.load(key: 1, on: eventLoopGroup)
127127

128-
XCTAssertNoThrow(try identityLoader.dispatchQueue(on: eventLoopGroup))
128+
XCTAssertNoThrow(try identityLoader.execute())
129129

130130
XCTAssertTrue(try value1.map { $0 }.wait() == 1)
131131
XCTAssertTrue(try value2.map { $0 }.wait() == 1)
@@ -152,7 +152,7 @@ final class DataLoaderTests: XCTestCase {
152152
let value1 = try identityLoader.load(key: "A", on: eventLoopGroup)
153153
let value2 = try identityLoader.load(key: "B", on: eventLoopGroup)
154154

155-
XCTAssertNoThrow(try identityLoader.dispatchQueue(on: eventLoopGroup))
155+
XCTAssertNoThrow(try identityLoader.execute())
156156

157157
XCTAssertTrue(try value1.wait() == "A")
158158
XCTAssertTrue(try value2.wait() == "B")
@@ -161,7 +161,7 @@ final class DataLoaderTests: XCTestCase {
161161
let value3 = try identityLoader.load(key: "A", on: eventLoopGroup)
162162
let value4 = try identityLoader.load(key: "C", on: eventLoopGroup)
163163

164-
XCTAssertNoThrow(try identityLoader.dispatchQueue(on: eventLoopGroup))
164+
XCTAssertNoThrow(try identityLoader.execute())
165165

166166
XCTAssertTrue(try value3.wait() == "A")
167167
XCTAssertTrue(try value4.wait() == "C")
@@ -172,7 +172,7 @@ final class DataLoaderTests: XCTestCase {
172172
let value7 = try identityLoader.load(key: "C", on: eventLoopGroup)
173173

174174

175-
XCTAssertNoThrow(try identityLoader.dispatchQueue(on: eventLoopGroup))
175+
XCTAssertNoThrow(try identityLoader.execute())
176176

177177
XCTAssertTrue(try value5.wait() == "A")
178178
XCTAssertTrue(try value6.wait() == "B")
@@ -199,7 +199,7 @@ final class DataLoaderTests: XCTestCase {
199199
let value1 = try identityLoader.load(key: "A", on: eventLoopGroup)
200200
let value2 = try identityLoader.load(key: "B", on: eventLoopGroup)
201201

202-
XCTAssertNoThrow(try identityLoader.dispatchQueue(on: eventLoopGroup))
202+
XCTAssertNoThrow(try identityLoader.execute())
203203

204204
XCTAssertTrue(try value1.wait() == "A")
205205
XCTAssertTrue(try value2.wait() == "B")
@@ -210,7 +210,7 @@ final class DataLoaderTests: XCTestCase {
210210
let value3 = try identityLoader.load(key: "A", on: eventLoopGroup)
211211
let value4 = try identityLoader.load(key: "B", on: eventLoopGroup)
212212

213-
XCTAssertNoThrow(try identityLoader.dispatchQueue(on: eventLoopGroup))
213+
XCTAssertNoThrow(try identityLoader.execute())
214214

215215
XCTAssertTrue(try value3.wait() == "A")
216216
XCTAssertTrue(try value4.wait() == "B")
@@ -236,7 +236,7 @@ final class DataLoaderTests: XCTestCase {
236236
let value1 = try identityLoader.load(key: "A", on: eventLoopGroup)
237237
let value2 = try identityLoader.load(key: "B", on: eventLoopGroup)
238238

239-
XCTAssertNoThrow(try identityLoader.dispatchQueue(on: eventLoopGroup))
239+
XCTAssertNoThrow(try identityLoader.execute())
240240

241241
XCTAssertTrue(try value1.wait() == "A")
242242
XCTAssertTrue(try value2.wait() == "B")
@@ -247,7 +247,7 @@ final class DataLoaderTests: XCTestCase {
247247
let value3 = try identityLoader.load(key: "A", on: eventLoopGroup)
248248
let value4 = try identityLoader.load(key: "B", on: eventLoopGroup)
249249

250-
XCTAssertNoThrow(try identityLoader.dispatchQueue(on: eventLoopGroup))
250+
XCTAssertNoThrow(try identityLoader.execute())
251251

252252
XCTAssertTrue(try value3.wait() == "A")
253253
XCTAssertTrue(try value4.wait() == "B")
@@ -275,7 +275,7 @@ final class DataLoaderTests: XCTestCase {
275275
let value1 = try identityLoader.load(key: "A", on: eventLoopGroup)
276276
let value2 = try identityLoader.load(key: "B", on: eventLoopGroup)
277277

278-
XCTAssertNoThrow(try identityLoader.dispatchQueue(on: eventLoopGroup))
278+
XCTAssertNoThrow(try identityLoader.execute())
279279

280280
XCTAssertTrue(try value1.wait() == "A")
281281
XCTAssertTrue(try value2.wait() == "B")
@@ -303,7 +303,7 @@ final class DataLoaderTests: XCTestCase {
303303
let value1 = try identityLoader.load(key: "A", on: eventLoopGroup)
304304
let value2 = try identityLoader.load(key: "B", on: eventLoopGroup)
305305

306-
XCTAssertNoThrow(try identityLoader.dispatchQueue(on: eventLoopGroup))
306+
XCTAssertNoThrow(try identityLoader.execute())
307307

308308
XCTAssertTrue(try value1.wait() == "X")
309309
XCTAssertTrue(try value2.wait() == "B")
@@ -314,7 +314,7 @@ final class DataLoaderTests: XCTestCase {
314314
let value3 = try identityLoader.load(key: "A", on: eventLoopGroup)
315315
let value4 = try identityLoader.load(key: "B", on: eventLoopGroup)
316316

317-
XCTAssertNoThrow(try identityLoader.dispatchQueue(on: eventLoopGroup))
317+
XCTAssertNoThrow(try identityLoader.execute())
318318

319319
XCTAssertTrue(try value3.wait() == "X")
320320
XCTAssertTrue(try value4.wait() == "B")
@@ -343,7 +343,7 @@ final class DataLoaderTests: XCTestCase {
343343
let value1 = try identityLoader.load(key: "A", on: eventLoopGroup)
344344
let value2 = try identityLoader.load(key: "B", on: eventLoopGroup)
345345

346-
XCTAssertNoThrow(try identityLoader.dispatchQueue(on: eventLoopGroup))
346+
XCTAssertNoThrow(try identityLoader.execute())
347347

348348
XCTAssertTrue(try value1.wait() == "X")
349349
XCTAssertTrue(try value2.wait() == "B")
@@ -354,7 +354,7 @@ final class DataLoaderTests: XCTestCase {
354354
let value3 = try identityLoader.load(key: "A", on: eventLoopGroup)
355355
let value4 = try identityLoader.load(key: "B", on: eventLoopGroup)
356356

357-
XCTAssertNoThrow(try identityLoader.dispatchQueue(on: eventLoopGroup))
357+
XCTAssertNoThrow(try identityLoader.execute())
358358

359359
XCTAssertTrue(try value3.wait() == "Y")
360360
XCTAssertTrue(try value4.wait() == "Y")

0 commit comments

Comments
 (0)