QNPartsUploadPerformer.m 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. //
  2. // QNPartsUploadPerformer.m
  3. // QiniuSDK
  4. //
  5. // Created by yangsen on 2020/12/1.
  6. // Copyright © 2020 Qiniu. All rights reserved.
  7. //
  8. #import "QNLogUtil.h"
  9. #import "QNAsyncRun.h"
  10. #import "QNUpToken.h"
  11. #import "QNZoneInfo.h"
  12. #import "QNUploadOption.h"
  13. #import "QNConfiguration.h"
  14. #import "QNUploadInfo.h"
  15. #import "QNUploadRegionInfo.h"
  16. #import "QNRecorderDelegate.h"
  17. #import "QNUploadDomainRegion.h"
  18. #import "QNPartsUploadPerformer.h"
  19. #import "QNUpProgress.h"
  20. #import "QNRequestTransaction.h"
  21. #define kQNRecordFileInfoKey @"recordFileInfo"
  22. #define kQNRecordZoneInfoKey @"recordZoneInfo"
  23. @interface QNPartsUploadPerformer()
  24. @property (nonatomic, copy) NSString *key;
  25. @property (nonatomic, copy) NSString *fileName;
  26. @property (nonatomic, strong) id <QNUploadSource> uploadSource;
  27. @property (nonatomic, strong) QNUpToken *token;
  28. @property (nonatomic, strong) QNUploadOption *option;
  29. @property (nonatomic, strong) QNConfiguration *config;
  30. @property (nonatomic, strong) id <QNRecorderDelegate> recorder;
  31. @property (nonatomic, copy) NSString *recorderKey;
  32. @property (nonatomic, strong) NSNumber *recoveredFrom;
  33. @property (nonatomic, strong) id <QNUploadRegion> targetRegion;
  34. @property (nonatomic, strong) id <QNUploadRegion> currentRegion;
  35. @property (nonatomic, strong) QNUploadInfo *uploadInfo;
  36. @property(nonatomic, strong) QNUpProgress *progress;
  37. @property(nonatomic, strong) NSMutableArray <QNRequestTransaction *> *uploadTransactions;
  38. @end
  39. @implementation QNPartsUploadPerformer
  40. - (instancetype)initWithSource:(id<QNUploadSource>)uploadSource
  41. fileName:(NSString *)fileName
  42. key:(NSString *)key
  43. token:(QNUpToken *)token
  44. option:(QNUploadOption *)option
  45. configuration:(QNConfiguration *)config
  46. recorderKey:(NSString *)recorderKey {
  47. if (self = [super init]) {
  48. _uploadSource = uploadSource;
  49. _fileName = fileName;
  50. _key = key;
  51. _token = token;
  52. _option = option;
  53. _config = config;
  54. _recorder = config.recorder;
  55. _recorderKey = recorderKey;
  56. [self initData];
  57. }
  58. return self;
  59. }
  60. - (void)initData {
  61. self.uploadTransactions = [NSMutableArray array];
  62. if (!self.uploadInfo) {
  63. self.uploadInfo = [self getDefaultUploadInfo];
  64. }
  65. [self recoverUploadInfoFromRecord];
  66. }
  67. - (BOOL)couldReloadInfo {
  68. return [self.uploadInfo couldReloadSource];
  69. }
  70. - (BOOL)reloadInfo {
  71. self.recoveredFrom = nil;
  72. [self.uploadInfo clearUploadState];
  73. return [self.uploadInfo reloadSource];
  74. }
  75. - (void)switchRegion:(id <QNUploadRegion>)region {
  76. self.currentRegion = region;
  77. if (!self.targetRegion) {
  78. self.targetRegion = region;
  79. }
  80. }
  81. - (void)notifyProgress:(BOOL)isCompleted {
  82. if (self.uploadInfo == nil) {
  83. return;
  84. }
  85. if (isCompleted) {
  86. [self.progress notifyDone:self.key totalBytes:[self.uploadInfo getSourceSize]];
  87. } else {
  88. [self.progress progress:self.key uploadBytes:[self.uploadInfo uploadSize] totalBytes:[self.uploadInfo getSourceSize]];
  89. }
  90. }
  91. - (void)recordUploadInfo {
  92. NSString *key = self.recorderKey;
  93. if (self.recorder == nil || key == nil || key.length == 0) {
  94. return;
  95. }
  96. @synchronized (self) {
  97. NSDictionary *zoneInfo = [self.currentRegion zoneInfo].detailInfo;
  98. NSDictionary *uploadInfo = [self.uploadInfo toDictionary];
  99. if (zoneInfo && uploadInfo) {
  100. NSDictionary *info = @{kQNRecordZoneInfoKey : zoneInfo,
  101. kQNRecordFileInfoKey : uploadInfo};
  102. NSData *data = [NSJSONSerialization dataWithJSONObject:info options:NSJSONWritingPrettyPrinted error:nil];
  103. if (data) {
  104. [self.recorder set:key data:data];
  105. }
  106. }
  107. }
  108. QNLogInfo(@"key:%@ recorderKey:%@ recordUploadInfo", self.key, self.recorderKey);
  109. }
  110. - (void)removeUploadInfoRecord {
  111. self.recoveredFrom = nil;
  112. [self.uploadInfo clearUploadState];
  113. [self.recorder del:self.recorderKey];
  114. QNLogInfo(@"key:%@ recorderKey:%@ removeUploadInfoRecord", self.key, self.recorderKey);
  115. }
  116. - (void)recoverUploadInfoFromRecord {
  117. QNLogInfo(@"key:%@ recorderKey:%@ recorder:%@ recoverUploadInfoFromRecord", self.key, self.recorderKey, self.recorder);
  118. NSString *key = self.recorderKey;
  119. if (self.recorder == nil || key == nil || [key isEqualToString:@""]) {
  120. return;
  121. }
  122. NSData *data = [self.recorder get:key];
  123. if (data == nil) {
  124. QNLogInfo(@"key:%@ recorderKey:%@ recoverUploadInfoFromRecord data:nil", self.key, self.recorderKey);
  125. return;
  126. }
  127. NSError *error = nil;
  128. NSDictionary *info = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error];
  129. if (error != nil || ![info isKindOfClass:[NSDictionary class]]) {
  130. QNLogInfo(@"key:%@ recorderKey:%@ recoverUploadInfoFromRecord json error", self.key, self.recorderKey);
  131. [self.recorder del:self.key];
  132. return;
  133. }
  134. QNZoneInfo *zoneInfo = [QNZoneInfo zoneInfoFromDictionary:info[kQNRecordZoneInfoKey]];
  135. QNUploadInfo *recoverUploadInfo = [self getFileInfoWithDictionary:info[kQNRecordFileInfoKey]];
  136. if (zoneInfo && self.uploadInfo && [recoverUploadInfo isValid]
  137. && [self.uploadInfo isSameUploadInfo:recoverUploadInfo]) {
  138. QNLogInfo(@"key:%@ recorderKey:%@ recoverUploadInfoFromRecord valid", self.key, self.recorderKey);
  139. [recoverUploadInfo checkInfoStateAndUpdate];
  140. self.uploadInfo = recoverUploadInfo;
  141. QNUploadDomainRegion *region = [[QNUploadDomainRegion alloc] init];
  142. [region setupRegionData:zoneInfo];
  143. self.currentRegion = region;
  144. self.targetRegion = region;
  145. self.recoveredFrom = @([recoverUploadInfo uploadSize]);
  146. } else {
  147. QNLogInfo(@"key:%@ recorderKey:%@ recoverUploadInfoFromRecord invalid", self.key, self.recorderKey);
  148. [self.recorder del:self.key];
  149. self.currentRegion = nil;
  150. self.targetRegion = nil;
  151. self.recoveredFrom = nil;
  152. }
  153. }
  154. - (QNRequestTransaction *)createUploadRequestTransaction {
  155. QNRequestTransaction *transaction = [[QNRequestTransaction alloc] initWithConfig:self.config
  156. uploadOption:self.option
  157. targetRegion:self.targetRegion
  158. currentRegion:self.currentRegion
  159. key:self.key
  160. token:self.token];
  161. @synchronized (self) {
  162. [self.uploadTransactions addObject:transaction];
  163. }
  164. return transaction;
  165. }
  166. - (void)destroyUploadRequestTransaction:(QNRequestTransaction *)transaction {
  167. if (transaction) {
  168. @synchronized (self) {
  169. [self.uploadTransactions removeObject:transaction];
  170. }
  171. }
  172. }
  173. - (QNUploadInfo *)getFileInfoWithDictionary:(NSDictionary *)fileInfoDictionary {
  174. return nil;
  175. }
  176. - (QNUploadInfo *)getDefaultUploadInfo {
  177. return nil;
  178. }
  179. - (void)serverInit:(void (^)(QNResponseInfo * _Nullable,
  180. QNUploadRegionRequestMetrics * _Nullable,
  181. NSDictionary * _Nullable))completeHandler {}
  182. - (void)uploadNextData:(void (^)(BOOL stop,
  183. QNResponseInfo * _Nullable,
  184. QNUploadRegionRequestMetrics * _Nullable,
  185. NSDictionary * _Nullable))completeHandler {}
  186. - (void)completeUpload:(void (^)(QNResponseInfo * _Nullable,
  187. QNUploadRegionRequestMetrics * _Nullable,
  188. NSDictionary * _Nullable))completeHandler {}
  189. - (QNUpProgress *)progress {
  190. if (_progress == nil) {
  191. _progress = [QNUpProgress progress:self.option.progressHandler byteProgress:self.option.byteProgressHandler];
  192. }
  193. return _progress;
  194. }
  195. @end