14
14
#import " QNUpToken.h"
15
15
#import " QNResponseInfo.h"
16
16
#import " QNFixedZone.h"
17
+ #import " QNSingleFlight.h"
18
+
17
19
18
20
@interface QNAutoZoneCache : NSObject
19
21
@property (nonatomic , strong )NSMutableDictionary *cache;
@@ -69,6 +71,16 @@ - (QNZonesInfo *)zonesInfoForKey:(NSString *)cacheKey{
69
71
70
72
@end
71
73
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
+
72
84
@interface QNAutoZone ()
73
85
74
86
@property (nonatomic , strong )NSMutableDictionary *cache;
@@ -78,6 +90,15 @@ @interface QNAutoZone()
78
90
@end
79
91
@implementation QNAutoZone
80
92
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
+
81
102
- (instancetype )init {
82
103
if (self = [super init ]) {
83
104
_cache = [NSMutableDictionary new ];
@@ -122,24 +143,43 @@ - (void)preQuery:(QNUpToken *)token
122
143
ret (0 , [QNResponseInfo successResponse ], nil );
123
144
return ;
124
145
}
125
-
126
- QNRequestTransaction *transaction = [self createUploadRequestTransaction: token];
127
146
128
147
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 ) {
131
150
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
+ }];
133
167
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 ) {
135
176
QNZonesInfo *zonesInfo = [QNZonesInfo infoWithDictionary: response];
136
177
[self .lock lock ];
137
178
[self .cache setValue: zonesInfo forKey: cacheKey];
138
179
[self .lock unlock ];
139
180
[[QNAutoZoneCache share ] cache: response forKey: cacheKey];
140
181
ret (0 , responseInfo, metrics);
141
182
} else {
142
-
143
183
if (responseInfo.isConnectionBroken ) {
144
184
ret (kQNNetworkError , responseInfo, metrics);
145
185
} else {
@@ -150,7 +190,6 @@ - (void)preQuery:(QNUpToken *)token
150
190
ret (0 , responseInfo, metrics);
151
191
}
152
192
}
153
- [self destroyUploadRequestTransaction: transaction];
154
193
}];
155
194
}
156
195
0 commit comments