More tweaks to progress tracking
Run synchronous requests in custom runloop mode again
Showing
6 changed files
with
59 additions
and
54 deletions
@@ -266,7 +266,8 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | @@ -266,7 +266,8 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | ||
266 | NSTimeInterval timeOutSeconds; | 266 | NSTimeInterval timeOutSeconds; |
267 | 267 | ||
268 | // Will be YES when a HEAD request will handle the content-length before this request starts | 268 | // Will be YES when a HEAD request will handle the content-length before this request starts |
269 | - BOOL shouldResetProgressIndicators; | 269 | + BOOL shouldResetUploadProgress; |
270 | + BOOL shouldResetDownloadProgress; | ||
270 | 271 | ||
271 | // Used by HEAD requests when showAccurateProgress is YES to preset the content-length for this request | 272 | // Used by HEAD requests when showAccurateProgress is YES to preset the content-length for this request |
272 | ASIHTTPRequest *mainRequest; | 273 | ASIHTTPRequest *mainRequest; |
@@ -385,6 +386,9 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | @@ -385,6 +386,9 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | ||
385 | 386 | ||
386 | // An ID that uniquely identifies this request - primarily used for debugging persistent connections | 387 | // An ID that uniquely identifies this request - primarily used for debugging persistent connections |
387 | NSNumber *requestID; | 388 | NSNumber *requestID; |
389 | + | ||
390 | + // Will be ASIHTTPRequestRunLoopMode for synchronous requests, NSDefaultRunLoopMode for all other requests | ||
391 | + NSString *runLoopMode; | ||
388 | } | 392 | } |
389 | 393 | ||
390 | #pragma mark init / dealloc | 394 | #pragma mark init / dealloc |
@@ -466,10 +470,10 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | @@ -466,10 +470,10 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | ||
466 | // Called when authorisation is needed, as we only find out we don't have permission to something when the upload is complete | 470 | // Called when authorisation is needed, as we only find out we don't have permission to something when the upload is complete |
467 | - (void)removeUploadProgressSoFar; | 471 | - (void)removeUploadProgressSoFar; |
468 | 472 | ||
469 | -// Called when we get a content-length header and shouldResetProgressIndicators is true | 473 | +// Called when we get a content-length header and shouldResetDownloadProgress is true |
470 | - (void)incrementDownloadSizeBy:(long long)length; | 474 | - (void)incrementDownloadSizeBy:(long long)length; |
471 | 475 | ||
472 | -// Called when a request starts and shouldResetProgressIndicators is true | 476 | +// Called when a request starts and shouldResetUploadProgress is true |
473 | // Also called (with a negative length) to remove the size of the underlying buffer used for uploading | 477 | // Also called (with a negative length) to remove the size of the underlying buffer used for uploading |
474 | - (void)incrementUploadSizeBy:(long long)length; | 478 | - (void)incrementUploadSizeBy:(long long)length; |
475 | 479 | ||
@@ -723,7 +727,8 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | @@ -723,7 +727,8 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | ||
723 | @property (retain) NSMutableData *postBody; | 727 | @property (retain) NSMutableData *postBody; |
724 | @property (assign,readonly) unsigned long long contentLength; | 728 | @property (assign,readonly) unsigned long long contentLength; |
725 | @property (assign) unsigned long long postLength; | 729 | @property (assign) unsigned long long postLength; |
726 | -@property (assign) BOOL shouldResetProgressIndicators; | 730 | +@property (assign) BOOL shouldResetDownloadProgress; |
731 | +@property (assign) BOOL shouldResetUploadProgress; | ||
727 | @property (assign) ASIHTTPRequest *mainRequest; | 732 | @property (assign) ASIHTTPRequest *mainRequest; |
728 | @property (assign) BOOL showAccurateProgress; | 733 | @property (assign) BOOL showAccurateProgress; |
729 | @property (assign,readonly) unsigned long long totalBytesRead; | 734 | @property (assign,readonly) unsigned long long totalBytesRead; |
This diff is collapsed. Click to expand it.
@@ -55,7 +55,7 @@ | @@ -55,7 +55,7 @@ | ||
55 | int requestsCount; | 55 | int requestsCount; |
56 | 56 | ||
57 | // When NO, this request will only update the progress indicator when it completes | 57 | // When NO, this request will only update the progress indicator when it completes |
58 | - // When YES, this request will update the progress indicator according to how much data it has recieved so far | 58 | + // When YES, this request will update the progress indicator according to how much data it has received so far |
59 | // When YES, the queue will first perform HEAD requests for all GET requests in the queue, so it can calculate the total download size before it starts | 59 | // When YES, the queue will first perform HEAD requests for all GET requests in the queue, so it can calculate the total download size before it starts |
60 | // NO means better performance, because it skips this step for GET requests, and it won't waste time updating the progress indicator until a request completes | 60 | // NO means better performance, because it skips this step for GET requests, and it won't waste time updating the progress indicator until a request completes |
61 | // Set to YES if the size of a requests in the queue varies greatly for much more accurate results | 61 | // Set to YES if the size of a requests in the queue varies greatly for much more accurate results |
@@ -71,24 +71,12 @@ | @@ -71,24 +71,12 @@ | ||
71 | [self setRequestDidFailSelector:NULL]; | 71 | [self setRequestDidFailSelector:NULL]; |
72 | [self setRequestDidFinishSelector:NULL]; | 72 | [self setRequestDidFinishSelector:NULL]; |
73 | [self setQueueDidFinishSelector:NULL]; | 73 | [self setQueueDidFinishSelector:NULL]; |
74 | - [self setTotalBytesToUpload:0]; | ||
75 | - [self setBytesUploadedSoFar:0]; | ||
76 | - [self setTotalBytesToDownload:0]; | ||
77 | - [self setBytesDownloadedSoFar:0]; | ||
78 | [self setSuspended:YES]; | 74 | [self setSuspended:YES]; |
79 | } | 75 | } |
80 | 76 | ||
81 | 77 | ||
82 | - (void)go | 78 | - (void)go |
83 | { | 79 | { |
84 | - if (![self showAccurateProgress]) { | ||
85 | - if ([self downloadProgressDelegate]) { | ||
86 | - [self setTotalBytesToDownload:[self requestsCount]]; | ||
87 | - } | ||
88 | - if ([self uploadProgressDelegate]) { | ||
89 | - [self setTotalBytesToUpload:[self requestsCount]]; | ||
90 | - } | ||
91 | - } | ||
92 | [self setSuspended:NO]; | 80 | [self setSuspended:NO]; |
93 | } | 81 | } |
94 | 82 | ||
@@ -172,35 +160,33 @@ | @@ -172,35 +160,33 @@ | ||
172 | // If this is a GET request and we want accurate progress, perform a HEAD request first to get the content-length | 160 | // If this is a GET request and we want accurate progress, perform a HEAD request first to get the content-length |
173 | // We'll only do this before the queue is started | 161 | // We'll only do this before the queue is started |
174 | // If requests are added after the queue is started they will probably move the overall progress backwards anyway, so there's no value performing the HEAD requests first | 162 | // If requests are added after the queue is started they will probably move the overall progress backwards anyway, so there's no value performing the HEAD requests first |
175 | - // Instead, they'll update the total progress if and when they recieve a content-length header | 163 | + // Instead, they'll update the total progress if and when they receive a content-length header |
176 | - if ([[request requestMethod] isEqualToString:@"GET"] && [self isSuspended]) { | 164 | + if ([[request requestMethod] isEqualToString:@"GET"]) { |
177 | - ASIHTTPRequest *HEADRequest = [request HEADRequest]; | 165 | + if ([self isSuspended]) { |
178 | - [self addHEADOperation:HEADRequest]; | 166 | + ASIHTTPRequest *HEADRequest = [request HEADRequest]; |
179 | - | 167 | + [self addHEADOperation:HEADRequest]; |
180 | - if ([request shouldResetProgressIndicators]) { | 168 | + [request addDependency:HEADRequest]; |
181 | - [self resetProgressDelegate:[request downloadProgressDelegate]]; | 169 | + if ([request shouldResetDownloadProgress]) { |
182 | - } | 170 | + [self resetProgressDelegate:[request downloadProgressDelegate]]; |
183 | - | 171 | + [request setShouldResetDownloadProgress:NO]; |
184 | - //Tell the request not to reset the progress indicator when it gets a content-length, as we will get the length from the HEAD request | 172 | + } |
185 | - [request setShouldResetProgressIndicators:NO]; | ||
186 | - | ||
187 | - [request addDependency:HEADRequest]; | ||
188 | - | ||
189 | - // If we want to track uploading for this request accurately, we need to add the size of the post content to the total | ||
190 | - } else if (uploadProgressDelegate) { | ||
191 | - [request buildPostBody]; | ||
192 | - [self setTotalBytesToUpload:[self totalBytesToUpload]+[request postLength]]; | ||
193 | - | ||
194 | - | ||
195 | - if ([request shouldResetProgressIndicators]) { | ||
196 | - [self resetProgressDelegate:[request uploadProgressDelegate]]; | ||
197 | } | 173 | } |
198 | - | ||
199 | - [request setShouldResetProgressIndicators:NO]; | ||
200 | } | 174 | } |
175 | + [request buildPostBody]; | ||
176 | + [self request:nil incrementUploadSizeBy:[request postLength]]; | ||
177 | + | ||
178 | + | ||
179 | + } else { | ||
180 | + [self request:nil incrementDownloadSizeBy:1]; | ||
181 | + [self request:nil incrementUploadSizeBy:1]; | ||
201 | } | 182 | } |
183 | + // Tell the request not to increment the upload size when it starts, as we've already added its length | ||
184 | + if ([request shouldResetUploadProgress]) { | ||
185 | + [self resetProgressDelegate:[request uploadProgressDelegate]]; | ||
186 | + [request setShouldResetUploadProgress:NO]; | ||
187 | + } | ||
188 | + | ||
202 | [request setShowAccurateProgress:[self showAccurateProgress]]; | 189 | [request setShowAccurateProgress:[self showAccurateProgress]]; |
203 | - | ||
204 | 190 | ||
205 | [request setQueue:self]; | 191 | [request setQueue:self]; |
206 | [super addOperation:request]; | 192 | [super addOperation:request]; |
@@ -21,17 +21,18 @@ | @@ -21,17 +21,18 @@ | ||
21 | - (void)setMaxValue:(double)newMax; | 21 | - (void)setMaxValue:(double)newMax; |
22 | #endif | 22 | #endif |
23 | 23 | ||
24 | -// Called when the request recieves some data - bytes is the length of that data | 24 | +// Called when the request receives some data - bytes is the length of that data |
25 | -// bytes may be less than zero if a request needs to remove its progress so far | ||
26 | - (void)request:(ASIHTTPRequest *)request didReceiveBytes:(long long)bytes; | 25 | - (void)request:(ASIHTTPRequest *)request didReceiveBytes:(long long)bytes; |
27 | 26 | ||
28 | -// Called when the request sends some data. | 27 | +// Called when the request sends some data |
29 | // The first 32KB (128KB on older platforms) of data sent is not included in this amount because of limitations with the CFNetwork API | 28 | // The first 32KB (128KB on older platforms) of data sent is not included in this amount because of limitations with the CFNetwork API |
29 | +// bytes may be less than zero if a request needs to remove upload progress (probably because the request needs to run again) | ||
30 | - (void)request:(ASIHTTPRequest *)request didSendBytes:(long long)bytes; | 30 | - (void)request:(ASIHTTPRequest *)request didSendBytes:(long long)bytes; |
31 | 31 | ||
32 | // Called when a request needs to change the length of the content to download | 32 | // Called when a request needs to change the length of the content to download |
33 | - (void)request:(ASIHTTPRequest *)request incrementDownloadSizeBy:(long long)newLength; | 33 | - (void)request:(ASIHTTPRequest *)request incrementDownloadSizeBy:(long long)newLength; |
34 | 34 | ||
35 | // Called when a request needs to change the length of the content to upload | 35 | // Called when a request needs to change the length of the content to upload |
36 | +// newLength may be less than zero when a request needs to remove the size of the internal buffer from progress tracking | ||
36 | - (void)request:(ASIHTTPRequest *)request incrementUploadSizeBy:(long long)newLength; | 37 | - (void)request:(ASIHTTPRequest *)request incrementUploadSizeBy:(long long)newLength; |
37 | @end | 38 | @end |
@@ -182,7 +182,10 @@ IMPORTANT | @@ -182,7 +182,10 @@ IMPORTANT | ||
182 | BOOL success = (progress == 1.0); | 182 | BOOL success = (progress == 1.0); |
183 | GHAssertTrue(success,@"Failed to increment progress properly"); | 183 | GHAssertTrue(success,@"Failed to increment progress properly"); |
184 | 184 | ||
185 | - [networkQueue cancelAllOperations]; | 185 | + [networkQueue reset]; |
186 | + [networkQueue setDownloadProgressDelegate:self]; | ||
187 | + [networkQueue setDelegate:self]; | ||
188 | + [networkQueue setQueueDidFinishSelector:@selector(queueFinished:)]; | ||
186 | 189 | ||
187 | // This test will request gzipped content, but the content-length header we get on the HEAD request will be wrong, ASIHTTPRequest should fall back to simple progress | 190 | // This test will request gzipped content, but the content-length header we get on the HEAD request will be wrong, ASIHTTPRequest should fall back to simple progress |
188 | // This is to workaround an issue Apache has with HEAD requests for dynamically generated content when accepting gzip - it returns the content-length of a gzipped empty body | 191 | // This is to workaround an issue Apache has with HEAD requests for dynamically generated content when accepting gzip - it returns the content-length of a gzipped empty body |
@@ -210,14 +213,13 @@ IMPORTANT | @@ -210,14 +213,13 @@ IMPORTANT | ||
210 | [self setAddMoreRequestsQueue:[ASINetworkQueue queue]]; | 213 | [self setAddMoreRequestsQueue:[ASINetworkQueue queue]]; |
211 | [[self addMoreRequestsQueue] setDownloadProgressDelegate:self]; | 214 | [[self addMoreRequestsQueue] setDownloadProgressDelegate:self]; |
212 | [[self addMoreRequestsQueue] setDelegate:self]; | 215 | [[self addMoreRequestsQueue] setDelegate:self]; |
213 | - [[self addMoreRequestsQueue] setShowAccurateProgress:NO]; | 216 | + [[self addMoreRequestsQueue] setShowAccurateProgress:YES]; |
214 | [[self addMoreRequestsQueue]setQueueDidFinishSelector:@selector(addMoreRequestsQueueFinished:)]; | 217 | [[self addMoreRequestsQueue]setQueueDidFinishSelector:@selector(addMoreRequestsQueueFinished:)]; |
215 | 218 | ||
216 | requestsFinishedCount = 0; | 219 | requestsFinishedCount = 0; |
217 | 220 | ||
218 | complete = NO; | 221 | complete = NO; |
219 | progress = 0; | 222 | progress = 0; |
220 | - [[self addMoreRequestsQueue] setShowAccurateProgress:YES]; | ||
221 | 223 | ||
222 | int i; | 224 | int i; |
223 | for (i=0; i<5; i++) { | 225 | for (i=0; i<5; i++) { |
@@ -311,13 +313,18 @@ IMPORTANT | @@ -311,13 +313,18 @@ IMPORTANT | ||
311 | [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.25]]; | 313 | [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.25]]; |
312 | } | 314 | } |
313 | [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]]; | 315 | [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]]; |
314 | - BOOL success = (progress > 0.95); | 316 | + BOOL success = (progress == 1.0f); |
315 | GHAssertTrue(success,@"Failed to increment progress properly"); | 317 | GHAssertTrue(success,@"Failed to increment progress properly"); |
316 | 318 | ||
317 | //Now test again with accurate progress | 319 | //Now test again with accurate progress |
318 | complete = NO; | 320 | complete = NO; |
319 | progress = 0; | 321 | progress = 0; |
320 | - [networkQueue cancelAllOperations]; | 322 | + [networkQueue reset]; |
323 | + [networkQueue setUploadProgressDelegate:self]; | ||
324 | + [networkQueue setDelegate:self]; | ||
325 | + [networkQueue setShowAccurateProgress:NO]; | ||
326 | + [networkQueue setRequestDidFailSelector:@selector(uploadFailed:)]; | ||
327 | + [networkQueue setQueueDidFinishSelector:@selector(queueFinished:)]; | ||
321 | [networkQueue setShowAccurateProgress:YES]; | 328 | [networkQueue setShowAccurateProgress:YES]; |
322 | 329 | ||
323 | for (i=0; i<3; i++) { | 330 | for (i=0; i<3; i++) { |
@@ -335,7 +342,7 @@ IMPORTANT | @@ -335,7 +342,7 @@ IMPORTANT | ||
335 | [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.25]]; | 342 | [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.25]]; |
336 | } | 343 | } |
337 | [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]]; | 344 | [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]]; |
338 | - success = (progress > 0.95); | 345 | + success = (progress == 1.0f); |
339 | GHAssertTrue(success,@"Failed to increment progress properly"); | 346 | GHAssertTrue(success,@"Failed to increment progress properly"); |
340 | 347 | ||
341 | } | 348 | } |
@@ -709,7 +716,7 @@ IMPORTANT | @@ -709,7 +716,7 @@ IMPORTANT | ||
709 | success = (amountDownloaded == 1036935); | 716 | success = (amountDownloaded == 1036935); |
710 | GHAssertTrue(success,@"Failed to complete the download"); | 717 | GHAssertTrue(success,@"Failed to complete the download"); |
711 | 718 | ||
712 | - success = (progress > 0.95); | 719 | + success = (progress == 1.0f); |
713 | GHAssertTrue(success,@"Failed to increment progress properly"); | 720 | GHAssertTrue(success,@"Failed to increment progress properly"); |
714 | 721 | ||
715 | 722 | ||
@@ -1112,6 +1119,10 @@ IMPORTANT | @@ -1112,6 +1119,10 @@ IMPORTANT | ||
1112 | 1119 | ||
1113 | - (void)testQueueFinishedCalledOnFailure | 1120 | - (void)testQueueFinishedCalledOnFailure |
1114 | { | 1121 | { |
1122 | + [self performSelectorOnMainThread:@selector(runTestQueueFinishedCalledOnFailureTest) withObject:nil waitUntilDone:YES]; | ||
1123 | +} | ||
1124 | +- (void)runTestQueueFinishedCalledOnFailureTest | ||
1125 | +{ | ||
1115 | complete = NO; | 1126 | complete = NO; |
1116 | ASINetworkQueue *networkQueue = [[ASINetworkQueue queue] retain]; | 1127 | ASINetworkQueue *networkQueue = [[ASINetworkQueue queue] retain]; |
1117 | [networkQueue setDelegate:self]; | 1128 | [networkQueue setDelegate:self]; |
@@ -1136,7 +1147,9 @@ IMPORTANT | @@ -1136,7 +1147,9 @@ IMPORTANT | ||
1136 | 1147 | ||
1137 | queueFinishedCallCount = 0; | 1148 | queueFinishedCallCount = 0; |
1138 | complete = NO; | 1149 | complete = NO; |
1139 | - [networkQueue reset]; | 1150 | + |
1151 | + [networkQueue release]; | ||
1152 | + networkQueue = [[ASINetworkQueue queue] retain]; | ||
1140 | [networkQueue setDelegate:self]; | 1153 | [networkQueue setDelegate:self]; |
1141 | [networkQueue setQueueDidFinishSelector:@selector(queueFailureFinishCallOnce:)]; | 1154 | [networkQueue setQueueDidFinishSelector:@selector(queueFailureFinishCallOnce:)]; |
1142 | [networkQueue setMaxConcurrentOperationCount:1]; | 1155 | [networkQueue setMaxConcurrentOperationCount:1]; |
@@ -1150,7 +1163,7 @@ IMPORTANT | @@ -1150,7 +1163,7 @@ IMPORTANT | ||
1150 | 1163 | ||
1151 | dateStarted = [NSDate date]; | 1164 | dateStarted = [NSDate date]; |
1152 | while (!complete) { | 1165 | while (!complete) { |
1153 | - [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]]; | 1166 | + [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0f]]; |
1154 | if ([dateStarted timeIntervalSinceNow] < -10) { | 1167 | if ([dateStarted timeIntervalSinceNow] < -10) { |
1155 | break; | 1168 | break; |
1156 | } | 1169 | } |
-
Please register or login to post a comment