|
1
|
1 #pragma once
|
|
|
2
|
|
|
3 namespace ProfileCache {
|
|
|
4 inline file::ptr FetchFile(const char * context, const char * name, const char * webURL, t_filetimestamp acceptableAge, abort_callback & abort) {
|
|
|
5 const double timeoutVal = 5;
|
|
|
6
|
|
|
7 auto path = core_api::pathInProfile( context );
|
|
|
8 auto fsLocal = filesystem::get(path);
|
|
|
9 fsLocal->make_directory(path, abort);
|
|
|
10 path.add_filename( name );
|
|
|
11
|
|
|
12 bool fetch = false;
|
|
|
13 file::ptr fLocal;
|
|
|
14
|
|
|
15 try {
|
|
|
16 fLocal = fsLocal->openWriteExisting(path, abort, timeoutVal );
|
|
|
17 fetch = fLocal->get_timestamp(abort) < filetimestamp_from_system_timer() - acceptableAge;
|
|
|
18 } catch(exception_io_not_found const &) {
|
|
|
19 fLocal = fsLocal->openWriteNew(path, abort, timeoutVal);
|
|
|
20 fetch = true;
|
|
|
21 }
|
|
|
22 if (fetch) {
|
|
|
23 try {
|
|
|
24 fLocal->resize(0, abort);
|
|
|
25 file::ptr fRemote;
|
|
|
26 filesystem::g_open(fRemote, webURL, filesystem::open_mode_read, abort);
|
|
|
27 file::g_transfer_file(fRemote, fLocal, abort );
|
|
|
28 } catch(exception_io const &) {
|
|
|
29 fLocal.release();
|
|
|
30 try {
|
|
|
31 retryOnSharingViolation(timeoutVal, abort, [&] {fsLocal->remove(path, abort);} );
|
|
|
32 } catch(...) {}
|
|
|
33 throw;
|
|
|
34 }
|
|
|
35 fLocal->seek(0, abort);
|
|
|
36 }
|
|
|
37 return fLocal;
|
|
|
38 }
|
|
|
39 };
|