1
1
mirror of https://github.com/kean/Nuke.git synced 2024-11-28 12:04:01 +03:00

Fix a concurrency warning in RateLimiter

This commit is contained in:
kean 2024-08-18 13:08:57 -04:00
parent d650baf7f5
commit 70b92f03d6

View File

@ -18,7 +18,7 @@ final class RateLimiter {
// This type isn't really Sendable and requires the caller to use the same // This type isn't really Sendable and requires the caller to use the same
// queue as it does for synchronization. // queue as it does for synchronization.
private let bucket: TokenBucket private var bucket: TokenBucket
private var pending = LinkedList<Work>() // fast append, fast remove first private var pending = LinkedList<Work>() // fast append, fast remove first
private var isExecutingPendingTasks = false private var isExecutingPendingTasks = false
@ -55,7 +55,7 @@ final class RateLimiter {
let bucketRate = 1000.0 / bucket.rate let bucketRate = 1000.0 / bucket.rate
let delay = Int(2.1 * bucketRate) // 14 ms for rate 80 (default) let delay = Int(2.1 * bucketRate) // 14 ms for rate 80 (default)
let bounds = min(100, max(15, delay)) let bounds = min(100, max(15, delay))
#warning("correct?") // TODO: make sure this is correct
Task { Task {
try? await Task.sleep(nanoseconds: UInt64(bounds) * 1_000_000) try? await Task.sleep(nanoseconds: UInt64(bounds) * 1_000_000)
self.executePendingTasks() self.executePendingTasks()
@ -73,7 +73,7 @@ final class RateLimiter {
} }
} }
private final class TokenBucket { private struct TokenBucket {
let rate: Double let rate: Double
private let burst: Double // maximum bucket size private let burst: Double // maximum bucket size
private var bucket: Double private var bucket: Double
@ -89,7 +89,7 @@ private final class TokenBucket {
} }
/// Returns `true` if the closure was executed, `false` if dropped. /// Returns `true` if the closure was executed, `false` if dropped.
func execute(_ work: () -> Bool) -> Bool { mutating func execute(_ work: () -> Bool) -> Bool {
refill() refill()
guard bucket >= 1.0 else { guard bucket >= 1.0 else {
return false // bucket is empty return false // bucket is empty
@ -100,7 +100,7 @@ private final class TokenBucket {
return true return true
} }
private func refill() { private mutating func refill() {
let now = CFAbsoluteTimeGetCurrent() let now = CFAbsoluteTimeGetCurrent()
bucket += rate * max(0, now - timestamp) // rate * (time delta) bucket += rate * max(0, now - timestamp) // rate * (time delta)
timestamp = now timestamp = now