Skip to content

elfenlaid/rate-limiter

Repository files navigation

Combine RateLimiter

A naive rate limiter for API calls or database queries:

let scheduler = DispatchQueue.testScheduler
// 2 calls every 1 second
let strategy = QueueThroughputStrategy(rate: UInt(2), interval: .seconds(1), scheduler: scheduler)

var values: [Int] = []

(1...5).publisher
    .rateLimited(by: strategy)
    .sink(receiveValue: {
        values.append($0)
    })
    .store(in: &cancellables)

(1...5).publisher
    .rateLimited(by: strategy)
    .sink(receiveValue: {
        values.append($0)
    })
    .store(in: &cancellables)

scheduler.advance(by: .seconds(0))

// Rate limiter starts immediately, and throughputs events up to the initial capacity:
print(values) // [1,1]

// Now limiter waits for its interval to pass...
scheduler.advance(by: .seconds(1))

// ... to get another round of values
print(values) // [1,1, 2,2]

Airtable Example

By default, Airtable's Public REST API has a rate limit of 5 requests per second per base. Let's describe the limit in terms of QueueThroughputStrategy:

extension URLSession {
    private static let strategy = QueueThroughputStrategy(
        rate: UInt(5),
        interval: .seconds(1),
        scheduler: DispatchQueue(label: "com.airtable.network")
    )
}

Now we can use it with sessions.dataTaskPublisher:

extension URLSession {
        public func listRecords(request: URLRequest) -> AnyPublisher<Data, Error> {
            dataTaskPublisher(for: request)
            .map(\.data)
            .rateLimited(by: Self.strategy)
            .receive(on: DispatchQueue.main)
        }
}

One thing to notice here, .rateLimited emits events on a provided scheduler. So, don't forget to reschedule the events.

F.A.Q.

Is it enough to rate-limit the API?

Surely not. The implementation is a kinda soft limiter. Requests can be delayed in flight and went entirely out of sync with the rate limiter publisher.

Make sure to add a circuit breaker retry:

Is it safe and well tested?

Surely not. I've used it in a couple of my projects without consequences. The library is tested to some extent. Alas, it's extremely hard to write custom Publishers. So, beware of race conditions.

About

No description or website provided.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages