Skip to content

Instantly share code, notes, and snippets.

@fitomad
Created June 21, 2019 07:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fitomad/80ee6074bb99e279de09c0595bce6a84 to your computer and use it in GitHub Desktop.
Save fitomad/80ee6074bb99e279de09c0595bce6a84 to your computer and use it in GitHub Desktop.
Beta version of an URLSession + Combine that detected a 429 HTTP error (rate limit) then delay N seconds and retry.
/**
URL HTTP request to a server with a
3 request per 10 seconds rate limit.
Thanks to combine it's super easy detected
rate limit and retry after N seconds.
This is a *beta* version.
Things TO-DO...
- Apply `delay` + `retry` only to 429 HTTP error
- Better performance. Queues?... Maybe
*/
private func performRequest() -> Void
{
guard let testURL = URL(string: "http://127.0.0.1:5000") else
{
return
}
let publisher = URLSession.shared.dataTaskPublisher(for: testURL)
.tryMap { (data: Data, response: URLResponse) -> String? in
guard let httpResponse = response as? HTTPURLResponse else
{
throw MyError.networkError
}
if httpResponse.statusCode == 429
{
self.isLimitExceed = true
throw MyError.requestLimitExceed
}
return String(data: data, encoding: .utf8)
}
.delay(for: 10, scheduler: DispatchQueue.main) // Wait 10 seconds before retry
.retry(1) // Retry only one more time
.sink(receiveValue: { (content: String?) -> Void in
if let content = content
{
print(content)
}
})
}
...
enum MyError: Error
{
case networkError
case requestLimitExceed
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment