Skip to content

Commit 4797f57

Browse files
Prepare isExpired to pass a margin for slower scenarios (#20)
* move to 250ms for slow suscriptions * Move margin to variable and set default value to 250ms * Bump dependencies * Fix CI * Try with margin * Pass margin to isExpired too
1 parent 806b4e6 commit 4797f57

File tree

5 files changed

+27
-14
lines changed

5 files changed

+27
-14
lines changed

Sources/Publishers/Publishers.RemoveExpired.swift

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import Combine
22

33
public extension Publisher {
4-
func removeExpired() -> Publishers.RemoveExpired<Self>
4+
func removeExpired(margin: TimeInterval = taskDefaultMargin) -> Publishers.RemoveExpired<Self>
55
where Output: Taskable {
6-
Publishers.RemoveExpired(upstream: self)
6+
Publishers.RemoveExpired(upstream: self, margin: margin)
77
}
88
}
99

@@ -15,13 +15,15 @@ public extension Publishers {
1515
public typealias Failure = Upstream.Failure
1616

1717
public let upstream: Upstream
18+
private let margin: TimeInterval
1819

19-
public init(upstream: Upstream) {
20+
public init(upstream: Upstream, margin: TimeInterval) {
2021
self.upstream = upstream
22+
self.margin = margin
2123
}
2224

2325
public func receive<S: Subscriber>(subscriber: S) where Upstream.Failure == S.Failure, Output == S.Input {
24-
upstream.subscribe(Inner(downstream: subscriber))
26+
upstream.subscribe(Inner(downstream: subscriber, margin: margin))
2527
}
2628
}
2729
}
@@ -31,17 +33,19 @@ extension Publishers.RemoveExpired {
3133
where Downstream.Input == Output, Downstream.Failure == Upstream.Failure, Output: Taskable {
3234
let combineIdentifier = CombineIdentifier()
3335
private let downstream: Downstream
36+
private let margin: TimeInterval
3437

35-
fileprivate init(downstream: Downstream) {
38+
fileprivate init(downstream: Downstream, margin: TimeInterval) {
3639
self.downstream = downstream
40+
self.margin = margin
3741
}
3842

3943
func receive(subscription: Subscription) {
4044
downstream.receive(subscription: subscription)
4145
}
4246

4347
func receive(_ input: Upstream.Output) -> Subscribers.Demand {
44-
if input.isExpired {
48+
if input.isExpired(margin: margin) {
4549
return .none
4650
}
4751
return downstream.receive(input)

Sources/Publishers/Publishers.Scope.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import Foundation
33

44
public extension Publisher {
55
/// From a publisher, we can focus on a task and filter all expired and duplicated task. This publisher don't send value if at suscription moment there is a expired task.
6-
func scope<T: Taskable & Equatable>(_ transform: @escaping (Self.Output) -> T) -> AnyPublisher<T, Failure> {
6+
func scope<T: Taskable & Equatable>(_ transform: @escaping (Self.Output) -> T, margin: TimeInterval = taskDefaultMargin) -> AnyPublisher<T, Failure> {
77
map(transform)
8-
.removeExpired()
8+
.removeExpired(margin: margin)
99
.removeDuplicates()
1010
.eraseToAnyPublisher()
1111
}

Sources/Task/Task.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import Foundation
22

3+
public let taskDefaultMargin: TimeInterval = 0.250
4+
35
public class Task<T: Equatable, E: Error & Equatable>: Taskable, Equatable, CustomDebugStringConvertible {
46
public typealias Payload = T
57
public typealias Failure = E
@@ -50,9 +52,8 @@ public class Task<T: Equatable, E: Error & Equatable>: Taskable, Equatable, Cust
5052
status == .running
5153
}
5254

53-
public var isExpired: Bool {
54-
let margin: TimeInterval = 0.1 // 100ms for suscriptions propagations
55-
return started.timeIntervalSinceNow + expiration.value + margin < 0
55+
public func isExpired(margin: TimeInterval) -> Bool {
56+
started.timeIntervalSinceNow + expiration.value + margin < 0
5657
}
5758

5859
public var isRecentlySucceeded: Bool {

Sources/Task/Taskable.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ public protocol Taskable {
66

77
var isIdle: Bool { get }
88
var isRunning: Bool { get }
9-
var isExpired: Bool { get }
9+
func isExpired(margin: TimeInterval) -> Bool
1010
var isRecentlySucceeded: Bool { get }
1111
var isTerminal: Bool { get }
1212
var isSuccessful: Bool { get }
@@ -23,6 +23,12 @@ public protocol Taskable {
2323
static func success(_ payload: Payload, started: Date, expiration: TaskExpiration, tag: String?, progress: Decimal?) -> Self
2424
}
2525

26+
public extension Taskable {
27+
var isExpired: Bool {
28+
self.isExpired(margin: taskDefaultMargin)
29+
}
30+
}
31+
2632
public extension Taskable {
2733
static func idle(started: Date = Date(),
2834
tag: String? = nil,

Tests/PublishersTests+RemoveExpired.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ extension PublishersTests {
1010

1111
let subject = PassthroughSubject<Task<String, TestError>, Never>()
1212

13+
let margin: TimeInterval = 0.500
14+
1315
subject
14-
.removeExpired() // Filter the 2 expired task
16+
.removeExpired(margin: margin) // Filter the 2 expired task
1517
.removeDuplicates() // Pass only the first success task because the expired they never get here!
1618
.sink { task in
17-
XCTAssertFalse(task.isExpired)
19+
XCTAssertFalse(task.isExpired(margin: margin))
1820
expectation.fulfill()
1921
}
2022
.store(in: &cancellables)

0 commit comments

Comments
 (0)