@@ -25,7 +25,6 @@ class ParseFileController {
25
25
private final File cachePath ;
26
26
private final List <String > currentlyDownloadedFilesNames = new ArrayList <>();
27
27
28
-
29
28
private ParseHttpClient fileClient ;
30
29
31
30
public ParseFileController (ParseHttpClient restClient , File cachePath ) {
@@ -172,79 +171,80 @@ public Task<File> fetchAsync(
172
171
if (cancellationToken != null && cancellationToken .isCancelled ()) {
173
172
return Task .cancelled ();
174
173
}
175
- return Task .call (() -> {
176
- final File cacheFile = getCacheFile (state );
174
+ return Task .call (
175
+ () -> {
176
+ final File cacheFile = getCacheFile (state );
177
+
178
+ synchronized (lock ) {
179
+ if (currentlyDownloadedFilesNames .contains (state .name ())) {
180
+ while (currentlyDownloadedFilesNames .contains (state .name ())) {
181
+ lock .wait ();
182
+ }
183
+ }
177
184
178
- synchronized (lock ) {
179
- if (currentlyDownloadedFilesNames .contains (state .name ())) {
180
- while (currentlyDownloadedFilesNames .contains (state .name ())) {
181
- lock .wait ();
185
+ if (cacheFile .exists ()) {
186
+ return cacheFile ;
187
+ } else {
188
+ currentlyDownloadedFilesNames .add (state .name ());
189
+ }
182
190
}
183
- }
184
-
185
- if (cacheFile .exists ()) {
186
- return cacheFile ;
187
- } else {
188
- currentlyDownloadedFilesNames .add (state .name ());
189
- }
190
- }
191
191
192
- try {
193
- if (cancellationToken != null && cancellationToken .isCancelled ()) {
194
- throw new CancellationException ();
195
- }
196
-
197
- // Generate the temp file path for caching ParseFile content based on
198
- // ParseFile's url
199
- // The reason we do not write to the cacheFile directly is because there
200
- // is no way we can
201
- // verify if a cacheFile is complete or not. If download is interrupted
202
- // in the middle, next
203
- // time when we download the ParseFile, since cacheFile has already
204
- // existed, we will return
205
- // this incomplete cacheFile
206
- final File tempFile = getTempFile (state );
207
-
208
- // network
209
- final ParseFileRequest request =
210
- new ParseFileRequest (
211
- ParseHttpRequest .Method .GET , state .url (), tempFile );
212
-
213
- // We do not need to delete the temp file since we always try to
214
- // overwrite it
215
- Task <Void > downloadTask = request . executeAsync (
216
- fileClient (),
217
- null ,
218
- downloadProgressCallback ,
219
- cancellationToken
220
- );
221
- ParseTaskUtils .wait (downloadTask );
222
-
223
- // If the top-level task was cancelled, don't
224
- // actually set the data -- just move on.
225
- if (cancellationToken != null && cancellationToken .isCancelled ()) {
226
- throw new CancellationException ();
227
- }
228
- if (downloadTask .isFaulted ()) {
229
- ParseFileUtils .deleteQuietly (tempFile );
230
- throw new RuntimeException (downloadTask .getError ());
231
- }
232
-
233
- // Since we give the cacheFile pointer to
234
- // developers, it is not safe to guarantee
235
- // cacheFile always does not exist here, so it is
236
- // better to delete it manually,
237
- // otherwise moveFile may throw an exception.
238
- ParseFileUtils .deleteQuietly (cacheFile );
239
- ParseFileUtils .moveFile (tempFile , cacheFile );
240
- return cacheFile ;
241
- } finally {
242
- synchronized (lock ) {
243
- currentlyDownloadedFilesNames .remove (state .name ());
244
- lock .notifyAll ();
245
- }
246
- }
247
-
248
- }, ParseExecutors .io ());
192
+ try {
193
+ if (cancellationToken != null && cancellationToken .isCancelled ()) {
194
+ throw new CancellationException ();
195
+ }
196
+
197
+ // Generate the temp file path for caching ParseFile content based on
198
+ // ParseFile's url
199
+ // The reason we do not write to the cacheFile directly is because there
200
+ // is no way we can
201
+ // verify if a cacheFile is complete or not. If download is interrupted
202
+ // in the middle, next
203
+ // time when we download the ParseFile, since cacheFile has already
204
+ // existed, we will return
205
+ // this incomplete cacheFile
206
+ final File tempFile = getTempFile (state );
207
+
208
+ // network
209
+ final ParseFileRequest request =
210
+ new ParseFileRequest (
211
+ ParseHttpRequest .Method .GET , state .url (), tempFile );
212
+
213
+ // We do not need to delete the temp file since we always try to
214
+ // overwrite it
215
+ Task <Void > downloadTask =
216
+ request . executeAsync (
217
+ fileClient () ,
218
+ null ,
219
+ downloadProgressCallback ,
220
+ cancellationToken );
221
+ ParseTaskUtils .wait (downloadTask );
222
+
223
+ // If the top-level task was cancelled, don't
224
+ // actually set the data -- just move on.
225
+ if (cancellationToken != null && cancellationToken .isCancelled ()) {
226
+ throw new CancellationException ();
227
+ }
228
+ if (downloadTask .isFaulted ()) {
229
+ ParseFileUtils .deleteQuietly (tempFile );
230
+ throw new RuntimeException (downloadTask .getError ());
231
+ }
232
+
233
+ // Since we give the cacheFile pointer to
234
+ // developers, it is not safe to guarantee
235
+ // cacheFile always does not exist here, so it is
236
+ // better to delete it manually,
237
+ // otherwise moveFile may throw an exception.
238
+ ParseFileUtils .deleteQuietly (cacheFile );
239
+ ParseFileUtils .moveFile (tempFile , cacheFile );
240
+ return cacheFile ;
241
+ } finally {
242
+ synchronized (lock ) {
243
+ currentlyDownloadedFilesNames .remove (state .name ());
244
+ lock .notifyAll ();
245
+ }
246
+ }
247
+ },
248
+ ParseExecutors .io ());
249
249
}
250
250
}
0 commit comments