Skip to content

Commit ddafc4d

Browse files
NathanielVolfangojenkins
authored andcommitted
QPR-10445 -- Extend Retriever retries to INT_MAX and add remove_all() wrapper method to FileIO
1 parent 3a412b6 commit ddafc4d

3 files changed

Lines changed: 77 additions & 20 deletions

File tree

OREData/ored/utilities/fileio.cpp

Lines changed: 63 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -37,60 +37,104 @@ using QuantLib::Size;
3737

3838
// Defaults
3939
static Size _s_maxRetries = 7;
40-
static std::vector<Real> _s_backoff = {0.5, 1, 2, 4, 8, 16, 30};
40+
static Real _s_backoff = 0.5;
41+
static Real _s_maxBackoff = 30;
4142

4243
Size FileIO::maxRetries() { return _s_maxRetries; }
4344

44-
void FileIO::setMaxRetries(Size numOfRetries) {
45-
LOG("Setting FileOpen max retries to " << numOfRetries);
46-
_s_maxRetries = numOfRetries;
45+
Real FileIO::backoff() { return _s_backoff; }
46+
47+
Real FileIO::maxBackoff() { return _s_maxBackoff; }
48+
49+
void FileIO::setMaxRetries(Size n) {
50+
LOG("Setting FileOpen max retries to " << n);
51+
_s_maxRetries = n;
52+
}
53+
54+
void FileIO::setBackoff(Real b) {
55+
LOG("Setting FileOpen backoff to " << b);
56+
_s_backoff = b;
57+
}
58+
59+
void FileIO::setMaxBackoff(Real m) {
60+
LOG("Setting FileOpen max backoff to " << m);
61+
_s_maxBackoff = m;
4762
}
4863

4964
FILE* FileIO::fopen(const char* filename, const char* mode) {
5065
FILE* fp;
51-
int i = 0;
66+
Real currentBackoff = backoff();
5267

53-
do {
68+
for (Size i = 0; i <= maxRetries(); i++) {
5469
if (i > 0) {
55-
Real backoff = (i >= _s_backoff.size()) ? _s_backoff.back() : _s_backoff[i - 1];
56-
int backoffMillis = backoff * 1000;
57-
auto em = EventMessage("Error opening file '" + std::string(filename) + "'.");
70+
int backoffMillis = currentBackoff * 1000;
71+
auto em = EventMessage("Error opening file '" + std::string(filename) + "'. Retrying...");
5872
em.set("retry_count", i);
5973
em.set("retry_interval", backoffMillis);
6074
WLOG(em);
6175
std::this_thread::sleep_for(std::chrono::milliseconds(backoffMillis));
76+
Real nextBackoff = currentBackoff * 2;
77+
currentBackoff = (nextBackoff >= maxBackoff()) ? maxBackoff() : nextBackoff;
6278
}
6379

6480
fp = std::fopen(filename, mode);
65-
66-
i++;
67-
} while (fp == nullptr && i <= maxRetries());
81+
if (fp)
82+
break;
83+
}
6884

6985
return fp;
7086
}
7187

7288
bool FileIO::create_directories(const path& p) {
7389
bool res = false;
74-
int i = 0;
90+
Real currentBackoff = backoff();
7591

76-
do {
92+
for (Size i = 0; i <= maxRetries(); i++) {
7793
if (i > 0) {
78-
Real backoff = (i >= _s_backoff.size()) ? _s_backoff.back() : _s_backoff[i - 1];
79-
int backoffMillis = backoff * 1000;
80-
auto em = EventMessage("Error creating directory '" + p.string() + "'.");
94+
int backoffMillis = currentBackoff * 1000;
95+
auto em = EventMessage("Error creating directory '" + p.string() + "'. Retrying...");
8196
em.set("retry_count", i);
8297
em.set("retry_interval", backoffMillis);
8398
WLOG(em);
8499
std::this_thread::sleep_for(std::chrono::milliseconds(backoffMillis));
100+
Real nextBackoff = currentBackoff * 2;
101+
currentBackoff = (nextBackoff >= maxBackoff()) ? maxBackoff() : nextBackoff;
85102
}
86103

87104
try {
88105
res = boost::filesystem::create_directories(p);
106+
if (res)
107+
break;
89108
} catch (...) {
90109
}
110+
}
111+
112+
return res;
113+
}
114+
115+
bool FileIO::remove_all(const path& p) {
116+
bool res = false;
117+
Real currentBackoff = backoff();
118+
119+
for (Size i = 0; i <= maxRetries(); i++) {
120+
if (i > 0) {
121+
int backoffMillis = currentBackoff * 1000;
122+
auto em = EventMessage("Error emptying directory '" + p.string() + "'. Retrying...");
123+
em.set("retry_count", i);
124+
em.set("retry_interval", backoffMillis);
125+
WLOG(em);
126+
std::this_thread::sleep_for(std::chrono::milliseconds(backoffMillis));
127+
Real nextBackoff = currentBackoff * 2;
128+
currentBackoff = (nextBackoff >= maxBackoff()) ? maxBackoff() : nextBackoff;
129+
}
91130

92-
i++;
93-
} while (res == false && i <= maxRetries());
131+
try {
132+
res = boost::filesystem::remove_all(p);
133+
if (res)
134+
break;
135+
} catch (...) {
136+
}
137+
}
94138

95139
return res;
96140
}

OREData/ored/utilities/fileio.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,20 @@ class FileIO {
3939

4040
//! The maximum number of retries, defaults to 7
4141
static QuantLib::Size maxRetries();
42+
static QuantLib::Real backoff();
43+
static QuantLib::Real maxBackoff();
4244
static void setMaxRetries(QuantLib::Size);
45+
static void setBackoff(QuantLib::Real);
46+
static void setMaxBackoff(QuantLib::Real);
4347

4448
//! Retry wrapper for std::fopen
4549
static FILE* fopen(const char*, const char*);
4650

4751
//! Retry wrapper for boost::filesystem::create_directories
4852
static bool create_directories(const path&);
53+
54+
//! Retry wrapper for boost::filesystem::remove_all
55+
static bool remove_all(const path&);
4956
};
5057

5158
} // namespace data

OREData/ored/utilities/log.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,12 +266,18 @@ string EventMessage::json() const {
266266
value = boost::posix_time::to_iso_extended_string(time);
267267
} else if (p.second.type() == typeid(int)) {
268268
value = to_string(boost::any_cast<int>(p.second));
269+
} else if (p.second.type() == typeid(unsigned int)) {
270+
value = to_string(boost::any_cast<unsigned int>(p.second));
271+
} else if (p.second.type() == typeid(unsigned short)) {
272+
value = to_string(boost::any_cast<unsigned short>(p.second));
273+
} else if (p.second.type() == typeid(QuantLib::Size)) {
274+
value = to_string(boost::any_cast<QuantLib::Size>(p.second));
269275
} else if (p.second.type() == typeid(QuantLib::Real)) {
270276
value = to_string(boost::any_cast<QuantLib::Real>(p.second));
271277
} else if (p.second.type() == typeid(bool)) {
272278
value = to_string(boost::any_cast<bool>(p.second));
273279
} else {
274-
WLOG(StructuredMessage("Error", "Event Logging", "Unrecognised value type for key '" + p.first + "'",
280+
WLOG(StructuredMessage("Error", "Event Message Logging", "Unrecognised value type for key '" + p.first + "'",
275281
std::pair<string, string>()));
276282
}
277283

0 commit comments

Comments
 (0)