Skip to content

Commit 220f86f

Browse files
authored
Ensure the last element of reduction in the throttle is emitted and use appropriate delay (#292)
1 parent c889832 commit 220f86f

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

Sources/AsyncAlgorithms/AsyncThrottleSequence.swift

+10-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,16 @@ extension AsyncThrottleSequence: AsyncSequence {
8181
letstart= last ?? clock.now
8282
repeat{
8383
guardlet element =tryawait base.next()else{
84-
returnnil
84+
if reduced !=nil,let last {
85+
// ensure the rate of elements never exceeds the given interval
86+
letamount= interval - last.duration(to: clock.now)
87+
if amount >.zero {
88+
try?await clock.sleep(for: amount)
89+
}
90+
}
91+
// the last value is unable to have any subsequent
92+
// values so always return the last reduction
93+
return reduced
8594
}
8695
letreduction=awaitreducing(reduced, element)
8796
letnow= clock.now

Tests/AsyncAlgorithmsTests/TestThrottle.swift

+20-2
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ final class TestThrottle: XCTestCase {
7272
validate{
7373
"abcdefghijk|"
7474
$0.inputs[0].throttle(for:.steps(3), clock: $0.clock)
75-
"a--d--g--j-|"
75+
"a--d--g--j--[k|]"
7676
}
7777
}
7878

@@ -81,7 +81,7 @@ final class TestThrottle: XCTestCase {
8181
validate{
8282
"abcdefghijk|"
8383
$0.inputs[0].throttle(for:.steps(3), clock: $0.clock, latest:false)
84-
"a--b--e--h-|"
84+
"a--b--e--h--[k|]"
8585
}
8686
}
8787

@@ -138,4 +138,22 @@ final class TestThrottle: XCTestCase {
138138
"-a---c---e---g---i---k-|"
139139
}
140140
}
141+
142+
func test_trailing_delay_without_latest()throws{
143+
guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0,*)else{throwXCTSkip("Skipped due to Clock/Instant/Duration availability")}
144+
validate{
145+
"abcdefghijkl|"
146+
$0.inputs[0].throttle(for:.steps(3), clock: $0.clock, latest:false)
147+
"a--b--e--h--[k|]"
148+
}
149+
}
150+
151+
func test_trailing_delay_with_latest()throws{
152+
guard #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0,*)else{throwXCTSkip("Skipped due to Clock/Instant/Duration availability")}
153+
validate{
154+
"abcdefghijkl|"
155+
$0.inputs[0].throttle(for:.steps(3), clock: $0.clock, latest:true)
156+
"a--d--g--j--[l|]"
157+
}
158+
}
141159
}

0 commit comments

Comments
 (0)
close