Feature Request: Retry count #393

Closed
anthonycmain opened this Issue Jun 29, 2012 · 5 comments

Comments

Projects
None yet
5 participants
@anthonycmain

Until one of our devs finds the time, I was wondering if there were any plans, or anyone already has extending the library to have a retry count for connections.

I.e Im looking for a feature to retry a download 3 times if it times out/fails cause of a broken connection. Perhaps with a sleep period between attempts.

It would save me writing extra subs each time to support this feature

@mattt

This comment has been minimized.

Show comment
Hide comment
@mattt

mattt Jun 29, 2012

Contributor

Thanks for your suggestion, @anthonycmain.

This is something that a few people have requested, but each each use case had surprisingly different requirements in what the behavior should be, which leads me to believe that a general solution that's useful for all relevant cases is intractable.

I'm of the opinion that request retrying is an application concern (or perhaps even something for the user to initiate); it's not all that difficult to implement yourself:

- (void)downloadFileRetryingNumberOfTimes:(NSUInteger)ntimes 
                                  success:(void (^)(id responseObject))success 
                                  failure:(void (^)(NSError *error))failure
{
    if (ntimes <= 0) {
        if (failure) {
            NSError *error = ...;
            failure(error);
        }
    } else {
        [self getPath:@"/path/to/file" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
            if (success) {
                success(...);
            }
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            [self downloadFileRetryingNumberOfTimes:ntimes - 1 success:success failure:failure];
        }];
    }
}

Or something like that—essentially just a basic recursive method. I hope that helps.

Contributor

mattt commented Jun 29, 2012

Thanks for your suggestion, @anthonycmain.

This is something that a few people have requested, but each each use case had surprisingly different requirements in what the behavior should be, which leads me to believe that a general solution that's useful for all relevant cases is intractable.

I'm of the opinion that request retrying is an application concern (or perhaps even something for the user to initiate); it's not all that difficult to implement yourself:

- (void)downloadFileRetryingNumberOfTimes:(NSUInteger)ntimes 
                                  success:(void (^)(id responseObject))success 
                                  failure:(void (^)(NSError *error))failure
{
    if (ntimes <= 0) {
        if (failure) {
            NSError *error = ...;
            failure(error);
        }
    } else {
        [self getPath:@"/path/to/file" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
            if (success) {
                success(...);
            }
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            [self downloadFileRetryingNumberOfTimes:ntimes - 1 success:success failure:failure];
        }];
    }
}

Or something like that—essentially just a basic recursive method. I hope that helps.

@mattt mattt closed this Jun 29, 2012

@anthonycmain

This comment has been minimized.

Show comment
Hide comment
@anthonycmain

anthonycmain Jun 29, 2012

Brilliant nice response will do the job fine, think I might just add an additional sleep parameter, will share here if I do so

Brilliant nice response will do the job fine, think I might just add an additional sleep parameter, will share here if I do so

@liuxuan30

This comment has been minimized.

Show comment
Hide comment
@liuxuan30

liuxuan30 Nov 30, 2015

sorry for digging this out, but I need some advice that, should we be careful about retain circle when recursiving for self?

 failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            [self downloadFileRetryingNumberOfTimes:ntimes - 1 success:success failure:failure];
        }];
    }

the block hold self, and the next recursive downloadFileRetryingNumberOfTimes will lead to self hold the block?

sorry for digging this out, but I need some advice that, should we be careful about retain circle when recursiving for self?

 failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            [self downloadFileRetryingNumberOfTimes:ntimes - 1 success:success failure:failure];
        }];
    }

the block hold self, and the next recursive downloadFileRetryingNumberOfTimes will lead to self hold the block?

@kubatruhlar

This comment has been minimized.

Show comment
Hide comment
@kubatruhlar

kubatruhlar Aug 26, 2016

In my case, I frequently required this functionality so I came up wit this retry policy category that will help you with that AFNetworking+RetryPolicy

I know it's the old issue, but with respect to AFNetworking 3.0 it could serve well.

kubatruhlar commented Aug 26, 2016

In my case, I frequently required this functionality so I came up wit this retry policy category that will help you with that AFNetworking+RetryPolicy

I know it's the old issue, but with respect to AFNetworking 3.0 it could serve well.

@DingSoung

This comment has been minimized.

Show comment
Hide comment
@DingSoung

DingSoung Jul 20, 2017

Here is a example, support fail retry and timeout retry

+ (NSURLSessionDataTask *)requestWithFailRetry:(int)failRetry timeOutRetry:(int)timeOutRetry manager:(AFHTTPSessionManager *)manager url:(NSString *)url parameters:(NSDictionary *)parameters success:(void (^)(NSDictionary *data))success fail:(void (^)(NSError *error))fail {
    return [manager POST:url parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        //
    } progress:^(NSProgress * _Nonnull uploadProgress) {
        //
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [success:success];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if (failRetry <= 0 || timeOutRetry <= 0) {
            [fail:fail];
        } else {
            [YourClass requestWithFailRetry:failRetry - 1
                              timeOutRetry:error.code == NSURLErrorTimedOut ? timeOutRetry - 1 : timeOutRetry
                                   manager:manager
                                       url:url
                                parameters:parameters
                                   success:success
                                      fail:fail];
        }
    }];
}

Here is a example, support fail retry and timeout retry

+ (NSURLSessionDataTask *)requestWithFailRetry:(int)failRetry timeOutRetry:(int)timeOutRetry manager:(AFHTTPSessionManager *)manager url:(NSString *)url parameters:(NSDictionary *)parameters success:(void (^)(NSDictionary *data))success fail:(void (^)(NSError *error))fail {
    return [manager POST:url parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        //
    } progress:^(NSProgress * _Nonnull uploadProgress) {
        //
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [success:success];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if (failRetry <= 0 || timeOutRetry <= 0) {
            [fail:fail];
        } else {
            [YourClass requestWithFailRetry:failRetry - 1
                              timeOutRetry:error.code == NSURLErrorTimedOut ? timeOutRetry - 1 : timeOutRetry
                                   manager:manager
                                       url:url
                                parameters:parameters
                                   success:success
                                      fail:fail];
        }
    }];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment