Skip to content

Commit de25475

Browse files
committed
Merge pull request #1022 from GarthSnyder/dispatcher-cleanup
Dispatchers cleanup
2 parents 6a0f996 + 5ffba73 commit de25475

9 files changed

+74
-62
lines changed

Diff for: Sources/Dispatcher.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public struct DispatchQueueDispatcher: Dispatcher {
2727
let qos: DispatchQoS?
2828
let flags: DispatchWorkItemFlags?
2929

30-
init(queue: DispatchQueue, group: DispatchGroup? = nil, qos: DispatchQoS? = nil, flags: DispatchWorkItemFlags? = nil) {
30+
public init(queue: DispatchQueue, group: DispatchGroup? = nil, qos: DispatchQoS? = nil, flags: DispatchWorkItemFlags? = nil) {
3131
self.queue = queue
3232
self.group = group
3333
self.qos = qos
@@ -40,7 +40,7 @@ public struct DispatchQueueDispatcher: Dispatcher {
4040
}
4141

4242
// Avoid having to hard-code any particular defaults for qos or flags
43-
public extension DispatchQueue {
43+
internal extension DispatchQueue {
4444
final func asyncD(group: DispatchGroup? = nil, qos: DispatchQoS? = nil, flags: DispatchWorkItemFlags? = nil, execute body: @escaping () -> Void) {
4545
switch (qos, flags) {
4646
case (nil, nil):

Diff for: Sources/ConcurrencyLimitedDispatcher.swift renamed to Sources/Dispatchers/ConcurrencyLimitedDispatcher.swift

+6-2
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ import Foundation
33
/// A PromiseKit Dispatcher that allows no more than X simultaneous
44
/// executions at once.
55

6-
class ConcurrencyLimitedDispatcher: Dispatcher {
6+
public class ConcurrencyLimitedDispatcher: Dispatcher {
77

88
let queue: Dispatcher
99
let serializer: DispatchQueue = DispatchQueue(label: "CLD serializer")
1010

11-
private let semaphore: DispatchSemaphore
11+
let semaphore: DispatchSemaphore
1212

1313
/// A `PromiseKit` `Dispatcher` that allows no more than X simultaneous
1414
/// executions at once.
@@ -23,6 +23,10 @@ class ConcurrencyLimitedDispatcher: Dispatcher {
2323
semaphore = DispatchSemaphore(value: limit)
2424
}
2525

26+
public convenience init(limit: Int, queue: DispatchQueue) {
27+
self.init(limit: limit, queue: queue as Dispatcher)
28+
}
29+
2630
public func dispatch(_ body: @escaping () -> Void) {
2731
serializer.async {
2832
self.semaphore.wait()
File renamed without changes.
File renamed without changes.

Diff for: Sources/RateLimitedDispatcher.swift renamed to Sources/Dispatchers/RateLimitedDispatcher.swift

+6-2
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,16 @@ public class RateLimitedDispatcher: RateLimitedDispatcherBase {
3939
/// - perInterval: The length of the reference interval, in seconds.
4040
/// - queue: The DispatchQueue or Dispatcher on which to perform executions. May be serial or concurrent.
4141

42-
override init(maxDispatches: Int, perInterval interval: TimeInterval, queue: Dispatcher = DispatchQueue.global()) {
42+
override public init(maxDispatches: Int, perInterval interval: TimeInterval, queue: Dispatcher = DispatchQueue.global()) {
4343
latestAccrual = DispatchTime.now()
4444
super.init(maxDispatches: maxDispatches, perInterval: interval, queue: queue)
4545
tokensInBucket = Double(maxDispatches)
4646
}
4747

48+
public convenience init(maxDispatches: Int, perInterval interval: TimeInterval, queue: DispatchQueue) {
49+
self.init(maxDispatches: maxDispatches, perInterval: interval, queue: queue as Dispatcher)
50+
}
51+
4852
override func dispatchFromQueue() {
4953

5054
guard undispatched.count > 0 else { return }
@@ -97,7 +101,7 @@ public class RateLimitedDispatcher: RateLimitedDispatcherBase {
97101

98102
}
99103

100-
internal extension DispatchTime {
104+
extension DispatchTime {
101105
static func -(a: DispatchTime, b: DispatchTime) -> TimeInterval {
102106
let delta = a.uptimeNanoseconds - b.uptimeNanoseconds
103107
return TimeInterval(delta) / 1_000_000_000

Diff for: Sources/RateLimitedDispatcherBase.swift renamed to Sources/Dispatchers/RateLimitedDispatcherBase.swift

+9-9
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ public class RateLimitedDispatcherBase: Dispatcher {
66
let interval: TimeInterval
77
let queue: Dispatcher
88

9-
internal let serializer = DispatchQueue(label: "RLD serializer")
9+
let serializer = DispatchQueue(label: "RLD serializer")
1010

11-
internal var nDispatched = 0
12-
internal var undispatched = Queue<() -> Void>()
11+
var nDispatched = 0
12+
var undispatched = Queue<() -> Void>()
1313

14-
internal var cleanupNonce: Int64 = 0
15-
internal var cleanupWorkItem: DispatchWorkItem? { willSet { cleanupWorkItem?.cancel() }}
14+
var cleanupNonce: Int64 = 0
15+
var cleanupWorkItem: DispatchWorkItem? { willSet { cleanupWorkItem?.cancel() }}
1616

1717
public init(maxDispatches: Int, perInterval interval: TimeInterval, queue: Dispatcher = DispatchQueue.global()) {
1818
self.maxDispatches = maxDispatches
@@ -27,26 +27,26 @@ public class RateLimitedDispatcherBase: Dispatcher {
2727
}
2828
}
2929

30-
internal func dispatchFromQueue() {
30+
func dispatchFromQueue() {
3131
fatalError("Subclass responsibility")
3232
}
3333

34-
internal func recordActualStart() {
34+
func recordActualStart() {
3535
nDispatched -= 1
3636
dispatchFromQueue()
3737
if nDispatched == 0 && undispatched.isEmpty {
3838
scheduleCleanup()
3939
}
4040
}
4141

42-
internal func scheduleCleanup() {
42+
func scheduleCleanup() {
4343
cleanupWorkItem = DispatchWorkItem { [ weak self, nonce = self.cleanupNonce ] in
4444
self?.cleanup(nonce)
4545
}
4646
serializer.asyncAfter(deadline: DispatchTime.now() + interval, execute: cleanupWorkItem!)
4747
}
4848

49-
internal func cleanup(_ nonce: Int64) {
49+
func cleanup(_ nonce: Int64) {
5050
// Calls to cleanup() have to go through the serializer queue, so by by the time
5151
// we get here, more activity may have occurred. Ergo, verify nonce.
5252
guard nonce == cleanupNonce else { return }

Diff for: Sources/StrictRateLimitedDispatcher.swift renamed to Sources/Dispatchers/StrictRateLimitedDispatcher.swift

+5-1
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,16 @@ public class StrictRateLimitedDispatcher: RateLimitedDispatcherBase {
3737
/// - perInterval: The length of the reference interval, in seconds.
3838
/// - queue: The DispatchQueue or Dispatcher on which to perform executions. May be serial or concurrent.
3939

40-
override init(maxDispatches: Int, perInterval interval: TimeInterval, queue: Dispatcher = DispatchQueue.global()) {
40+
override public init(maxDispatches: Int, perInterval interval: TimeInterval, queue: Dispatcher = DispatchQueue.global()) {
4141
startTimeHistory = Queue<DispatchTime>(maxDepth: maxDispatches)
4242
immediateDispatchesAvailable = maxDispatches
4343
super.init(maxDispatches: maxDispatches, perInterval: interval, queue: queue)
4444
}
4545

46+
public convenience init(maxDispatches: Int, perInterval interval: TimeInterval, queue: DispatchQueue) {
47+
self.init(maxDispatches: maxDispatches, perInterval: interval, queue: queue as Dispatcher)
48+
}
49+
4650
override func dispatchFromQueue() {
4751

4852
cleanupNonce += 1

Diff for: Tests/Core/DispatcherTypeTests.swift

+31-16
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@ import Dispatch
22
@testable import PromiseKit
33
import XCTest
44

5-
class DispatcherTestBase: XCTestCase {
5+
class DispatcherTypeTests: XCTestCase {
66

77
struct ScenarioParameters {
88
let hiatusLikelihoods: [Double]
99
let noDelayLikelihoods: [Double]
1010
let intervals: [Double]
1111
let dispatches: [Int]
1212
}
13-
13+
1414
let standardParams = ScenarioParameters(
1515
hiatusLikelihoods: [ 0.3 ],
1616
noDelayLikelihoods: [ 0.75 ],
@@ -91,7 +91,7 @@ class DispatcherTestBase: XCTestCase {
9191
}
9292
}
9393

94-
let nHiatuses = delays.count { $0 > avgSlice }
94+
let nHiatuses = delays.lazy.filter { $0 > avgSlice }.count
9595

9696
scenarios.append(RateLimitScenario(maxDispatches: maxDispatches, interval: interval,
9797
hiatusLikelihood: hiatusLikelihoodPerInterval, nHiatuses: nHiatuses,
@@ -144,10 +144,6 @@ class DispatcherTestBase: XCTestCase {
144144
}
145145
return most
146146
}
147-
148-
}
149-
150-
class RateLimitTests: DispatcherTestBase {
151147

152148
func testRateLimitedDispatcher() {
153149
for scenario in scenarios {
@@ -166,10 +162,6 @@ class RateLimitTests: DispatcherTestBase {
166162
}
167163
}
168164

169-
}
170-
171-
class StrictRateLimitTests: DispatcherTestBase {
172-
173165
func testStrictRateLimitedDispatcher() {
174166
for scenario in scenarios {
175167
printScenarioDetails(scenario)
@@ -190,10 +182,6 @@ class StrictRateLimitTests: DispatcherTestBase {
190182
}
191183
}
192184

193-
}
194-
195-
class ConcurrencyLimitTests: DispatcherTestBase {
196-
197185
func testConcurrencyLimitedDispatcher() {
198186

199187
for scenario in scenarios {
@@ -233,8 +221,35 @@ class ConcurrencyLimitTests: DispatcherTestBase {
233221
}
234222
}
235223

236-
}
224+
// These aren't really "tests" per se; they just exercise all the various init types
225+
// to verify that none of them produce ambiguity warnings or recurse indefinitely,
226+
// and that DispatchQueue members are accessible.
237227

228+
func testRateLimitedDispatcherInit() {
229+
XCTAssertNotNil(RateLimitedDispatcher(maxDispatches: 1, perInterval: 1))
230+
XCTAssertNotNil(RateLimitedDispatcher(maxDispatches: 1, perInterval: 1, queue: DispatchQueue.main))
231+
XCTAssertNotNil(RateLimitedDispatcher(maxDispatches: 1, perInterval: 1, queue: CurrentThreadDispatcher()))
232+
XCTAssertNotNil(RateLimitedDispatcher(maxDispatches: 1, perInterval: 1, queue: .main))
233+
XCTAssertNotNil(RateLimitedDispatcher(maxDispatches: 1, perInterval: 1, queue: .global(qos: .background)))
234+
}
235+
236+
func testStrictRateLimitedDispatcherInit() {
237+
XCTAssertNotNil(StrictRateLimitedDispatcher(maxDispatches: 1, perInterval: 1))
238+
XCTAssertNotNil(StrictRateLimitedDispatcher(maxDispatches: 1, perInterval: 1, queue: DispatchQueue.main))
239+
XCTAssertNotNil(StrictRateLimitedDispatcher(maxDispatches: 1, perInterval: 1, queue: CurrentThreadDispatcher()))
240+
XCTAssertNotNil(StrictRateLimitedDispatcher(maxDispatches: 1, perInterval: 1, queue: .main))
241+
XCTAssertNotNil(StrictRateLimitedDispatcher(maxDispatches: 1, perInterval: 1, queue: .global(qos: .background)))
242+
}
243+
244+
func testConcurrencyLimitedDispatcherInit() {
245+
XCTAssertNotNil(ConcurrencyLimitedDispatcher(limit: 1))
246+
XCTAssertNotNil(ConcurrencyLimitedDispatcher(limit: 1, queue: DispatchQueue.main))
247+
XCTAssertNotNil(ConcurrencyLimitedDispatcher(limit: 1, queue: CurrentThreadDispatcher()))
248+
XCTAssertNotNil(ConcurrencyLimitedDispatcher(limit: 1, queue: .main))
249+
XCTAssertNotNil(ConcurrencyLimitedDispatcher(limit: 1, queue: .global(qos: .background)))
250+
}
251+
252+
}
238253

239254
// Reproducible, seedable RNG
240255

Diff for: Tests/Core/XCTestManifests.swift

+15-30
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,6 @@ extension CatchableTests {
5050
]
5151
}
5252

53-
extension ConcurrencyLimitTests {
54-
// DO NOT MODIFY: This is autogenerated, use:
55-
// `swift test --generate-linuxmain`
56-
// to regenerate.
57-
static let __allTests__ConcurrencyLimitTests = [
58-
("testConcurrencyLimitedDispatcher", testConcurrencyLimitedDispatcher),
59-
]
60-
}
61-
6253
extension DispatcherTests {
6354
// DO NOT MODIFY: This is autogenerated, use:
6455
// `swift test --generate-linuxmain`
@@ -75,6 +66,20 @@ extension DispatcherTests {
7566
]
7667
}
7768

69+
extension DispatcherTypeTests {
70+
// DO NOT MODIFY: This is autogenerated, use:
71+
// `swift test --generate-linuxmain`
72+
// to regenerate.
73+
static let __allTests__DispatcherTypeTests = [
74+
("testConcurrencyLimitedDispatcher", testConcurrencyLimitedDispatcher),
75+
("testConcurrencyLimitedDispatcherInit", testConcurrencyLimitedDispatcherInit),
76+
("testRateLimitedDispatcher", testRateLimitedDispatcher),
77+
("testRateLimitedDispatcherInit", testRateLimitedDispatcherInit),
78+
("testStrictRateLimitedDispatcher", testStrictRateLimitedDispatcher),
79+
("testStrictRateLimitedDispatcherInit", testStrictRateLimitedDispatcherInit),
80+
]
81+
}
82+
7883
extension GuaranteeTests {
7984
// DO NOT MODIFY: This is autogenerated, use:
8085
// `swift test --generate-linuxmain`
@@ -181,15 +186,6 @@ extension RaceTests {
181186
]
182187
}
183188

184-
extension RateLimitTests {
185-
// DO NOT MODIFY: This is autogenerated, use:
186-
// `swift test --generate-linuxmain`
187-
// to regenerate.
188-
static let __allTests__RateLimitTests = [
189-
("testRateLimitedDispatcher", testRateLimitedDispatcher),
190-
]
191-
}
192-
193189
extension RegressionTests {
194190
// DO NOT MODIFY: This is autogenerated, use:
195191
// `swift test --generate-linuxmain`
@@ -210,15 +206,6 @@ extension StressTests {
210206
]
211207
}
212208

213-
extension StrictRateLimitTests {
214-
// DO NOT MODIFY: This is autogenerated, use:
215-
// `swift test --generate-linuxmain`
216-
// to regenerate.
217-
static let __allTests__StrictRateLimitTests = [
218-
("testStrictRateLimitedDispatcher", testStrictRateLimitedDispatcher),
219-
]
220-
}
221-
222209
extension ThenableTests {
223210
// DO NOT MODIFY: This is autogenerated, use:
224211
// `swift test --generate-linuxmain`
@@ -310,8 +297,8 @@ public func __allTests() -> [XCTestCaseEntry] {
310297
testCase(AfterTests.__allTests__AfterTests),
311298
testCase(CancellationTests.__allTests__CancellationTests),
312299
testCase(CatchableTests.__allTests__CatchableTests),
313-
testCase(ConcurrencyLimitTests.__allTests__ConcurrencyLimitTests),
314300
testCase(DispatcherTests.__allTests__DispatcherTests),
301+
testCase(DispatcherTypeTests.__allTests__DispatcherTypeTests),
315302
testCase(GuaranteeTests.__allTests__GuaranteeTests),
316303
testCase(HangTests.__allTests__HangTests),
317304
testCase(JoinTests.__allTests__JoinTests),
@@ -320,10 +307,8 @@ public func __allTests() -> [XCTestCaseEntry] {
320307
testCase(PMKErrorTests.__allTests__PMKErrorTests),
321308
testCase(PromiseTests.__allTests__PromiseTests),
322309
testCase(RaceTests.__allTests__RaceTests),
323-
testCase(RateLimitTests.__allTests__RateLimitTests),
324310
testCase(RegressionTests.__allTests__RegressionTests),
325311
testCase(StressTests.__allTests__StressTests),
326-
testCase(StrictRateLimitTests.__allTests__StrictRateLimitTests),
327312
testCase(ThenableTests.__allTests__ThenableTests),
328313
testCase(WhenConcurrentTestCase_Swift.__allTests__WhenConcurrentTestCase_Swift),
329314
testCase(WhenTests.__allTests__WhenTests),

0 commit comments

Comments
 (0)