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
publicstructAsyncTimerSequence<C:Clock>:AsyncSequence{
1515
publictypealiasElement=C.Instant
16-
16+
1717
/// The iterator for an `AsyncTimerSequence` instance.
1818
publicstructIterator:AsyncIteratorProtocol{
1919
varclock:C?
2020
letinterval:C.Instant.Duration
2121
lettolerance:C.Instant.Duration?
2222
varlast: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-
letnow= clock.now
32-
letlast=self.last ?? now
33-
letnext= 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
publicmutatingfunc next()async->C.Instant?{
42-
guardlet clock = clock else{
31+
guardlet clock =self.clock else{
4332
returnnil
4433
}
45-
letnext=nextDeadline(clock)
34+
35+
letnext=(self.last ?? clock.now).advanced(by:self.interval)
4636
do{
47-
tryawait clock.sleep(until: next, tolerance: tolerance)
37+
tryawait clock.sleep(until: next, tolerance:self.tolerance)
4838
}catch{
4939
self.clock =nil
5040
returnnil
5141
}
5242
letnow= clock.now
53-
last = next
43+
self.last = next
5444
return now
5545
}
5646
}
57-
47+
5848
letclock:C
5949
letinterval:C.Instant.Duration
6050
lettolerance:C.Instant.Duration?
61-
51+
6252
/// Create an `AsyncTimerSequence` with a given repeating interval.
6353
publicinit(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
publicfunc makeAsyncIterator()->Iterator{
7060
Iterator(interval: interval, tolerance: tolerance, clock: clock)
7161
}

0 commit comments

Comments
 (0)
close