Networking/RetryingHTTPOperation.h
/* |
File: RetryingHTTPOperation.h |
Contains: Runs an HTTP request, with support for retries. |
Written by: DTS |
Copyright: Copyright (c) 2010 Apple Inc. All Rights Reserved. |
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. |
("Apple") in consideration of your agreement to the following |
terms, and your use, installation, modification or |
redistribution of this Apple software constitutes acceptance of |
these terms. If you do not agree with these terms, please do |
not use, install, modify or redistribute this Apple software. |
In consideration of your agreement to abide by the following |
terms, and subject to these terms, Apple grants you a personal, |
non-exclusive license, under Apple's copyrights in this |
original Apple software (the "Apple Software"), to use, |
reproduce, modify and redistribute the Apple Software, with or |
without modifications, in source and/or binary forms; provided |
that if you redistribute the Apple Software in its entirety and |
without modifications, you must retain this notice and the |
following text and disclaimers in all such redistributions of |
the Apple Software. Neither the name, trademarks, service marks |
or logos of Apple Inc. may be used to endorse or promote |
products derived from the Apple Software without specific prior |
written permission from Apple. Except as expressly stated in |
this notice, no other rights or licenses, express or implied, |
are granted by Apple herein, including but not limited to any |
patent rights that may be infringed by your derivative works or |
by other works in which the Apple Software may be incorporated. |
The Apple Software is provided by Apple on an "AS IS" basis. |
APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING |
WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, |
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING |
THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN |
COMBINATION WITH YOUR PRODUCTS. |
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, |
INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED |
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY |
OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION |
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY |
OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR |
OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF |
SUCH DAMAGE. |
*/ |
#import "QRunLoopOperation.h" |
/* |
RetryingHTTPOperation is a run loop based concurrent operation that initiates |
an HTTP request and handles retrying the request if it fails. There are a bunch |
of important points to note: |
o You should only use this class for idempotent requests, that is, requests that |
won't cause problems if they are retried. See RFC 2616 for more info on this topic. |
<http://www.ietf.org/rfc/rfc2616.txt> |
o It only retries requests where the result is likely to change. For example, |
there's no point retrying after an HTTP 404 status code. The (private) method |
-shouldRetryAfterError: controls what will and won't be retried. |
o The fundamental retry mechanism is a random expotential back-off algorithm. |
After a failure it choose a random delay between the 0 and the max delay. |
Each failure increases the maximum delay up to some overall limit. The current |
max delay sequence is one second, one minute, one hour, and six hours. |
You can tweak this by changing kRetryDelays. |
o In addition to this it does a fast retry if one of the following things happens: |
- The reachability status of the host associated with the request changes from |
unreachable to reachable. The change from unreachable to reachable indicates |
that the local network environment has changed sufficiently to justify a |
fresh retry. |
- Some other request to that host succeeds, which is a good indication that |
other requests will succeed as well. |
o The operation runs out of the run loop associated with the actualRunLoopThread |
inherited from QRunLoopOperation. If you observe any properties, expect them |
to be changed by that thread. |
o The exception is the hasHadRetryableFailure property. This property is always |
changed by the main thread. This makes it easy for main thread code to |
display a 'retrying' user interface. |
*/ |
@class QHTTPOperation; |
@class QReachabilityOperation; |
enum RetryingHTTPOperationState { |
kRetryingHTTPOperationStateNotStarted, |
kRetryingHTTPOperationStateGetting, |
kRetryingHTTPOperationStateWaitingToRetry, |
kRetryingHTTPOperationStateRetrying, |
kRetryingHTTPOperationStateFinished |
}; |
typedef enum RetryingHTTPOperationState RetryingHTTPOperationState; |
@interface RetryingHTTPOperation : QRunLoopOperation |
{ |
NSUInteger _sequenceNumber; |
NSURLRequest * _request; |
NSSet * _acceptableContentTypes; |
NSString * _responseFilePath; |
NSHTTPURLResponse * _response; |
NSData * _responseContent; |
RetryingHTTPOperationState _retryState; |
RetryingHTTPOperationState _retryStateClient; |
QHTTPOperation * _networkOperation; |
BOOL _hasHadRetryableFailure; |
NSUInteger _retryCount; |
NSTimer * _retryTimer; |
QReachabilityOperation * _reachabilityOperation; |
BOOL _notificationInstalled; |
} |
- (id)initWithRequest:(NSURLRequest *)request; |
// Initialise the operation to run the specified HTTP request. |
// Things that are configured by the init method and can't be changed. |
@property (copy, readonly) NSURLRequest * request; |
// Things you can configure before queuing the operation. |
// runLoopThread and runLoopModes inherited from QRunLoopOperation |
@property (copy, readwrite) NSSet * acceptableContentTypes; // default is nil, implying anything is acceptable |
@property (retain, readwrite) NSString * responseFilePath; // defaults to nil, which puts response into responseContent |
// Things that change as part of the progress of the operation. |
@property (assign, readonly ) RetryingHTTPOperationState retryState; // observable, always changes on actualRunLoopthread |
@property (assign, readonly ) RetryingHTTPOperationState retryStateClient; // observable, always changes on /main/ thread |
@property (assign, readonly ) BOOL hasHadRetryableFailure; // observable, always changes on /main/ thread |
@property (assign, readonly ) NSUInteger retryCount; // observable, always changes on actualRunLoopthread |
// Things that are only meaningful after the operation is finished. |
// error property inherited from QRunLoopOperation |
@property (copy, readonly ) NSString * responseMIMEType; // MIME type of responseContent |
@property (copy, readonly ) NSData * responseContent; // responseContent (nil if response content went to responseFilePath) |
@end |
Copyright © 2010 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2010-10-22