1414#import " QNUpToken.h"
1515#import " QNResponseInfo.h"
1616#import " QNFixedZone.h"
17+ #import " QNSingleFlight.h"
18+
1719
1820@interface QNAutoZoneCache : NSObject
1921@property (nonatomic , strong )NSMutableDictionary *cache;
@@ -69,6 +71,16 @@ - (QNZonesInfo *)zonesInfoForKey:(NSString *)cacheKey{
6971
7072@end
7173
74+ @interface QNUCQuerySingleFlightValue : NSObject
75+
76+ @property (nonatomic , strong )QNResponseInfo *responseInfo;
77+ @property (nonatomic , strong )NSDictionary *response;
78+ @property (nonatomic , strong )QNUploadRegionRequestMetrics *metrics;
79+
80+ @end
81+ @implementation QNUCQuerySingleFlightValue
82+ @end
83+
7284@interface QNAutoZone ()
7385
7486@property (nonatomic , strong )NSMutableDictionary *cache;
@@ -78,6 +90,15 @@ @interface QNAutoZone()
7890@end
7991@implementation QNAutoZone
8092
93+ + (QNSingleFlight *)UCQuerySingleFlight {
94+ static QNSingleFlight *singleFlight = nil ;
95+ static dispatch_once_t onceToken;
96+ dispatch_once (&onceToken, ^{
97+ singleFlight = [[QNSingleFlight alloc ] init ];
98+ });
99+ return singleFlight;
100+ }
101+
81102- (instancetype )init {
82103 if (self = [super init ]) {
83104 _cache = [NSMutableDictionary new ];
@@ -122,24 +143,43 @@ - (void)preQuery:(QNUpToken *)token
122143 ret (0 , [QNResponseInfo successResponse ], nil );
123144 return ;
124145 }
125-
126- QNRequestTransaction *transaction = [self createUploadRequestTransaction: token];
127146
128147 kQNWeakSelf ;
129- kQNWeakObj (transaction) ;
130- [transaction queryUploadHosts: ^(QNResponseInfo * _Nullable responseInfo, QNUploadRegionRequestMetrics * _Nullable metrics, NSDictionary * _Nullable response ) {
148+ QNSingleFlight *singleFlight = [QNAutoZone UCQuerySingleFlight ] ;
149+ [singleFlight perform: token.index action: ^(QNSingleFlightComplete _Nonnull complete ) {
131150 kQNStrongSelf ;
132- kQNStrongObj (transaction);
151+ QNRequestTransaction *transaction = [self createUploadRequestTransaction: token];
152+
153+ kQNWeakSelf ;
154+ kQNWeakObj (transaction);
155+ [transaction queryUploadHosts: ^(QNResponseInfo * _Nullable responseInfo, QNUploadRegionRequestMetrics * _Nullable metrics, NSDictionary * _Nullable response) {
156+ kQNStrongSelf ;
157+ kQNStrongObj (transaction);
158+
159+ QNUCQuerySingleFlightValue *value = [[QNUCQuerySingleFlightValue alloc ] init ];
160+ value.responseInfo = responseInfo;
161+ value.response = response;
162+ value.metrics = metrics;
163+ complete (value, nil );
164+
165+ [self destroyUploadRequestTransaction: transaction];
166+ }];
133167
134- if (responseInfo.isOK ) {
168+ } complete: ^(id _Nullable value, NSError * _Nullable error) {
169+ kQNStrongSelf ;
170+
171+ QNResponseInfo *responseInfo = [(QNUCQuerySingleFlightValue *)value responseInfo ];
172+ NSDictionary *response = [(QNUCQuerySingleFlightValue *)value response ];
173+ QNUploadRegionRequestMetrics *metrics = [(QNUCQuerySingleFlightValue *)value metrics ];
174+
175+ if (responseInfo && responseInfo.isOK ) {
135176 QNZonesInfo *zonesInfo = [QNZonesInfo infoWithDictionary: response];
136177 [self .lock lock ];
137178 [self .cache setValue: zonesInfo forKey: cacheKey];
138179 [self .lock unlock ];
139180 [[QNAutoZoneCache share ] cache: response forKey: cacheKey];
140181 ret (0 , responseInfo, metrics);
141182 } else {
142-
143183 if (responseInfo.isConnectionBroken ) {
144184 ret (kQNNetworkError , responseInfo, metrics);
145185 } else {
@@ -150,7 +190,6 @@ - (void)preQuery:(QNUpToken *)token
150190 ret (0 , responseInfo, metrics);
151191 }
152192 }
153- [self destroyUploadRequestTransaction: transaction];
154193 }];
155194}
156195
0 commit comments