35#include "BESTimeoutError.h"
36#include "RequestServiceTimer.h"
46using namespace std::chrono;
49#define prolog string("RequestServiceTimer::").append(__func__).append("() - ")
52static std::once_flag d_rst_init_once;
61 std::call_once(d_rst_init_once,RequestServiceTimer::initialize_instance);
65void RequestServiceTimer::initialize_instance() {
68 atexit(delete_instance);
72void RequestServiceTimer::delete_instance() {
86 std::lock_guard<std::recursive_mutex> lock_me(d_rst_lock_mutex);
88 if(timeout_ms > milliseconds{0}){
89 timeout_enabled =
true;
90 d_bes_timeout = timeout_ms;
93 timeout_enabled =
false;
94 d_bes_timeout = milliseconds{0};
96 start_time = steady_clock::now();
104 std::lock_guard<std::recursive_mutex> lock_me(d_rst_lock_mutex);
105 return duration_cast<milliseconds>(steady_clock::now() - start_time);
116 std::lock_guard<std::recursive_mutex> lock_me(d_rst_lock_mutex);
118 BESDEBUG(MODULE, prolog <<
"init remaining: " <<
remaining.count() << endl);
119 if (timeout_enabled) {
120 BESDEBUG(MODULE, prolog <<
"timeout enabled" << endl);
124 BESDEBUG(MODULE, prolog <<
"timeout disabled" << endl);
135 std::lock_guard<std::recursive_mutex> lock_me(d_rst_lock_mutex);
137 BESDEBUG(MODULE, prolog +
"remaining: " + std::to_string(dt.count()) +
" ms\n");
138 return timeout_enabled && (dt <= milliseconds {0});
145 std::lock_guard<std::recursive_mutex> lock_me(d_rst_lock_mutex);
146 timeout_enabled =
false;
149string RequestServiceTimer::dump(
bool pretty)
const {
150 std::stringstream ss;
151 if(!pretty){ ss<<
"["; }
152 ss <<
"RequestServiceTimer(" << (
void *)
this <<
") - ";
153 if(pretty){ ss << endl <<
" "; }
154 ss <<
"bes_timeout: " << d_bes_timeout.count() <<
"ms ";
155 if(pretty){ ss << endl <<
" "; }
156 ss <<
"start_time: " << duration_cast<seconds>(start_time.time_since_epoch()).count() <<
"s ";
157 if(pretty){ ss << endl <<
" "; }
158 ss <<
"is_timeout_enabled(): " << (is_timeout_enabled() ?
"true ":
"false ");
159 if(pretty){ ss << endl <<
" "; }
160 ss <<
"elapsed(): " <<
elapsed().count() <<
"ms ";
161 if(pretty){ ss << endl <<
" "; }
162 ss <<
"remaining(): " <<
remaining().count() <<
"ms ";
163 if(pretty){ ss << endl <<
" "; }
164 ss <<
"is_expired(): " << (
is_expired()?
"true":
"false");
165 if(pretty){ ss << endl; }
else{ ss <<
"]"; }
175void RequestServiceTimer::dump( ostream &strm )
const
177 strm << dump() << endl;
195 auto time_out_seconds = std::to_string(((
double)d_bes_timeout.count())/1000.00);
196 auto elapsed_time_seconds = std::to_string(((
double)
elapsed().count())/1000.00);
197 ERROR_LOG(prolog +
"ERROR: Time to transmit timeout expired. "+
198 "Elapsed Time: " + elapsed_time_seconds +
" " +
199 "max_time_to_transmit: " + time_out_seconds +
202 std::stringstream errMsg;
203 errMsg <<
"The request that you submitted timed out. The server was unable to begin transmitting" << endl;
204 errMsg <<
"a response in the time allowed. Requests processed by this server must begin transmitting" << endl;
205 errMsg <<
"the response in less than " << time_out_seconds <<
" seconds." << endl;
206 errMsg <<
"ElapsedTime: " << elapsed_time_seconds <<
" seconds" << endl;
207 errMsg <<
"Some things you can try: Reissue the request but change the amount of data requested." << endl;
208 errMsg <<
"You may reduce the size of the request by choosing just the variables you need and/or" << endl;
209 errMsg <<
"by using the DAP index based array sub-setting syntax to additionally limit the amount" << endl;
210 errMsg <<
"of data requested. You can also try requesting a different encoding for the response." << endl;
211 errMsg <<
"If you asked for the response to be encoded as a NetCDF-3 or NetCDF-4 file be aware" << endl;
212 errMsg <<
"that these response encodings are not streamable. In order to build these responses" << endl;
213 errMsg <<
"the server must write the entire response to a temporary file before it can begin to"<< endl;
214 errMsg <<
"send the response to the requesting client. Changing to a different encoding, such" << endl;
215 errMsg <<
"as DAP4 data, may allow the server to successfully respond to your request." << endl;
216 errMsg <<
"The service component that ran out of time said: " << endl;
217 errMsg << message << endl;
error thrown if there is a user syntax error in the request or any other user error
The master request service timer for this server; a singleton.
std::chrono::milliseconds remaining() const
If the time_out is enabled returns the time remaining. If the time_out is disabled returns 0.
static RequestServiceTimer * TheTimer()
Return a pointer to a singleton timer instance. If an instance does not exist it will create and init...
std::chrono::milliseconds elapsed() const
Return the time duration in milliseconds since the timer was started.
void throw_if_timeout_expired(const std::string &message, const std::string &file, const int line)
Checks the RequestServiceTimer to determine if the time spent servicing the request at this point has...
bool is_expired() const
if the time_out is disabled return false.
void start(std::chrono::milliseconds timeout_ms)
Set/Reset the timer start_time to now().
void disable_timeout()
Set the time_out is disabled.