-
Notifications
You must be signed in to change notification settings - Fork 514
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding support for automatically skipping cancelation if the amount l… #364
Changes from 5 commits
7fee01c
aedd21e
7dedb41
bbce106
31b6a41
99c6b91
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,6 +35,8 @@ typedef void (^PINURLSessionDataTaskCompletion)(NSURLSessionTask * _Nonnull task | |
|
||
@property (atomic, weak, nullable) id <PINURLSessionManagerDelegate> delegate; | ||
|
||
- (NSTimeInterval)weightedTimeToFirstByteForHost:(nonnull NSString *)host; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This would benefit from a brief documentation comment. |
||
|
||
#if DEBUG | ||
- (void)concurrentDownloads:(void (^_Nullable)(NSUInteger concurrentDownloads))concurrentDownloadsCompletion; | ||
#endif | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,9 @@ | |
NSString * const PINURLErrorDomain = @"PINURLErrorDomain"; | ||
|
||
@interface PINURLSessionManager () <NSURLSessionDelegate, NSURLSessionDataDelegate> | ||
{ | ||
NSCache *_timeToFirstByteCache; | ||
} | ||
|
||
@property (nonatomic, strong) NSLock *sessionManagerLock; | ||
@property (nonatomic, strong) NSURLSession *session; | ||
|
@@ -35,6 +38,9 @@ - (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)config | |
self.session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:self.operationQueue]; | ||
self.completions = [[NSMutableDictionary alloc] init]; | ||
self.delegateQueues = [[NSMutableDictionary alloc] init]; | ||
|
||
_timeToFirstByteCache = [[NSCache alloc] init]; | ||
_timeToFirstByteCache.countLimit = 25; | ||
} | ||
return self; | ||
} | ||
|
@@ -187,6 +193,60 @@ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didComp | |
}); | ||
} | ||
|
||
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didFinishCollectingMetrics:(NSURLSessionTaskMetrics *)metrics | ||
{ | ||
NSDate *requestStart = [NSDate distantFuture]; | ||
NSDate *firstByte = [NSDate distantPast]; | ||
|
||
BOOL valid = YES; | ||
|
||
for (NSURLSessionTaskTransactionMetrics *metric in metrics.transactionMetrics) { | ||
if (metric.requestStartDate == nil || metric.responseStartDate == nil) { | ||
//Only evaluate requests which completed their first byte. | ||
valid = NO; | ||
break; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems like you could drop the |
||
} | ||
if ([requestStart compare:metric.requestStartDate] != NSOrderedAscending) { | ||
requestStart = metric.requestStartDate; | ||
} | ||
if ([firstByte compare:metric.responseStartDate] != NSOrderedDescending) { | ||
firstByte = metric.responseStartDate; | ||
} | ||
} | ||
|
||
if (valid) { | ||
[self storeTimeToFirstByte:[firstByte timeIntervalSinceDate:requestStart] forHost:task.originalRequest.URL.host]; | ||
} | ||
} | ||
|
||
- (void)storeTimeToFirstByte:(NSTimeInterval)timeToFirstByte forHost:(NSString *)host | ||
{ | ||
[self lock]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if you can get away without locking. |
||
NSNumber *existingTimeToFirstByte = [_timeToFirstByteCache objectForKey:host]; | ||
if (existingTimeToFirstByte) { | ||
//We're obviously seriously weighting the latest result by doing this. Seems reasonable in | ||
//possibly changing network conditions. | ||
existingTimeToFirstByte = @( (timeToFirstByte + [existingTimeToFirstByte doubleValue]) / 2.0 ); | ||
} else { | ||
existingTimeToFirstByte = [NSNumber numberWithDouble:timeToFirstByte]; | ||
} | ||
[_timeToFirstByteCache setObject:existingTimeToFirstByte forKey:host]; | ||
[self unlock]; | ||
} | ||
|
||
- (NSTimeInterval)weightedTimeToFirstByteForHost:(NSString *)host | ||
{ | ||
NSTimeInterval timeToFirstByte; | ||
[self lock]; | ||
timeToFirstByte = [[_timeToFirstByteCache objectForKey:host] doubleValue]; | ||
if (timeToFirstByte <= 0 + DBL_EPSILON) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can drop the lock earlier (here). |
||
//return 0 if we're not sure. | ||
timeToFirstByte = 0; | ||
} | ||
[self unlock]; | ||
return timeToFirstByte; | ||
} | ||
|
||
#if DEBUG | ||
- (void)concurrentDownloads:(void (^_Nullable)(NSUInteger concurrentDownloads))concurrentDownloadsCompletion | ||
{ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I might say
> 0
here.