Skip to content

Instantly share code, notes, and snippets.

@LuizZak
Last active February 12, 2018 10:27
Show Gist options
  • Save LuizZak/91dc49309961e09ba28ad403e2a21a14 to your computer and use it in GitHub Desktop.
Save LuizZak/91dc49309961e09ba28ad403e2a21a14 to your computer and use it in GitHub Desktop.
PromiseKit retrying functions using encapsulated blocks that return promises
/// Retries the given throwing `block` as a promise `tries` times,
/// re-calling `block` another time until exhausting the tries.
func retry<T>(tries count: Int, block: () throws -> T) -> Promise<T> {
return Promise().thenRetry(tries: count, block: block)
}
/// Retries the given promise-returning `block` as a promise `tries` times,
/// re-calling `block` another time until exhausting the tries.
func retry<T>(tries count: Int, block: () -> Promise<T>) -> Promise<T> {
return Promise().thenRetry(tries: count, block: block)
}
extension Promise {
/// After succeeding this promise, re-tries the given block `tries` times, re-calling `block` another time
/// to try to fetch another promise until exhausting the tries.
func thenRetry<U>(tries count: Int, block: (T) throws -> Promise<U>) rethrows -> Promise<U> {
return self.then { ret in
return try block(ret)
}.recover { error -> Promise<U> in
if(count > 0) {
return try self.thenRetry(tries: count - 1, block: block)
}
throw error
}
}
/// After succeeding this promise, re-tries the given block `tries` times, re-calling `block` another time
/// to try to fetch another value until exhausting the tries.
func thenRetry<U>(tries count: Int, block: (T) throws -> U) -> Promise<U> {
return self.then { ret in
return try block(ret)
}.recover { error -> Promise<U> in
if(count > 0) {
return self.thenRetry(tries: count - 1, block: block)
}
throw error
}
}
}
/*
Example:
// As the start of a promise chain...
retry(tries: 3) {
myAsyncTask()
}.then {
// myAsyncTask succeeded within 3 retries!
}.error { error in
// myAsyncTask failed...
}
// As the continuation of a promise...
myAsyncTask().thenRetry(tries: 3) { result in
myOtherAsyncTask()
}.then {
// myOtherAsyncTask succeeded within 3 retries!
}.error { error in
// myAsyncTask or myOtherAsyncTask failed...
}
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment