Skip to content

Commit 6dfbfd5

Browse files
authored
Remove background correction in AsyncTimerSequence (#289)
# Motivation Currently, the `AsyncTimerSequence` is trying to correct for when an application becomes suspended and the timer might fire multiple times once the application gets foregrounded again. However, this is already handled by the `Clock` types themselves. The `SuspendingClock` is correcting for suspension of the app whereas the `ContinuousClock` is not. Additionally, this was not only hit by background an application but by just calling `Task.sleep` in the for-await loop that is consuming the sequence. # Modification This removes the part of the code in `AsyncTimerSequence` which corrected for suspension of the application.
1 parent 281e27c commit 6dfbfd5

File tree

1 file changed

+11
-21
lines changed

1 file changed

+11
-21
lines changed

Sources/AsyncAlgorithms/AsyncTimerSequence.swift

+11-21
Original file line numberDiff line numberDiff line change
@@ -13,59 +13,49 @@
1313
@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
1414
public struct AsyncTimerSequence<C: Clock>: AsyncSequence {
1515
public typealias Element = C.Instant
16-
16+
1717
/// The iterator for an `AsyncTimerSequence` instance.
1818
public struct Iterator: AsyncIteratorProtocol {
1919
var clock: C?
2020
let interval: C.Instant.Duration
2121
let tolerance: C.Instant.Duration?
2222
var last: C.Instant?
23-
23+
2424
init(interval: C.Instant.Duration, tolerance: C.Instant.Duration?, clock: C) {
2525
self.clock = clock
2626
self.interval = interval
2727
self.tolerance = tolerance
2828
}
29-
30-
func nextDeadline(_ clock: C) -> C.Instant {
31-
let now = clock.now
32-
let last = self.last ?? now
33-
let next = last.advanced(by: interval)
34-
if next < now {
35-
return last.advanced(by: interval * Int(((next.duration(to: now)) / interval).rounded(.up)))
36-
} else {
37-
return next
38-
}
39-
}
40-
29+
4130
public mutating func next() async -> C.Instant? {
42-
guard let clock = clock else {
31+
guard let clock = self.clock else {
4332
return nil
4433
}
45-
let next = nextDeadline(clock)
34+
35+
let next = (self.last ?? clock.now).advanced(by: self.interval)
4636
do {
47-
try await clock.sleep(until: next, tolerance: tolerance)
37+
try await clock.sleep(until: next, tolerance: self.tolerance)
4838
} catch {
4939
self.clock = nil
5040
return nil
5141
}
5242
let now = clock.now
53-
last = next
43+
self.last = next
5444
return now
5545
}
5646
}
57-
47+
5848
let clock: C
5949
let interval: C.Instant.Duration
6050
let tolerance: C.Instant.Duration?
61-
51+
6252
/// Create an `AsyncTimerSequence` with a given repeating interval.
6353
public init(interval: C.Instant.Duration, tolerance: C.Instant.Duration? = nil, clock: C) {
6454
self.clock = clock
6555
self.interval = interval
6656
self.tolerance = tolerance
6757
}
68-
58+
6959
public func makeAsyncIterator() -> Iterator {
7060
Iterator(interval: interval, tolerance: tolerance, clock: clock)
7161
}

0 commit comments

Comments
 (0)