client: prioritize network (including GUI RPC) over async file ops

This is an effort to make the Manager responsive even when
lots of VM jobs are starting up.
This commit is contained in:
David Anderson 2016-08-27 00:44:10 -07:00
parent bf71a029a5
commit c75d81f4c4
4 changed files with 30 additions and 28 deletions

View File

@ -1363,7 +1363,7 @@ void run_test_app() {
exit(1);
}
while (1) {
do_async_file_ops();
do_async_file_op();
if (at.async_copy == NULL) {
break;
}

View File

@ -325,21 +325,19 @@ void remove_async_verify(ASYNC_VERIFY* avp) {
// Note: if there are lots of pending operations,
// it's better to finish the oldest one before starting the rest
//
bool do_async_file_ops() {
void do_async_file_op() {
if (async_copies.size()) {
ASYNC_COPY* acp = async_copies[0];
if (acp->copy_chunk()) {
async_copies.erase(async_copies.begin());
delete acp;
}
return true;
return;
}
if (async_verifies.size()) {
if (async_verifies[0]->verify_chunk()) {
async_verifies.erase(async_verifies.begin());
}
return true;
}
return false;
}

View File

@ -91,6 +91,9 @@ extern std::vector<ASYNC_COPY*> async_copies;
extern void remove_async_copy(ASYNC_COPY*);
extern void remove_async_verify(ASYNC_VERIFY*);
extern bool do_async_file_ops();
inline bool have_async_file_op() {
return (async_verifies.size() || async_copies.size());
}
extern void do_async_file_op();
#endif

View File

@ -809,22 +809,27 @@ FDSET_GROUP all_fds;
// Spend x seconds either doing I/O (if possible) or sleeping.
//
void CLIENT_STATE::do_io_or_sleep(double x) {
void CLIENT_STATE::do_io_or_sleep(double max_time) {
int n;
struct timeval tv;
set_now();
double end_time = now + x;
//int loops = 0;
double end_time = now + max_time;
double time_remaining = max_time;
while (1) {
bool action = do_async_file_ops();
curl_fds.zero();
gui_rpc_fds.zero();
http_ops->get_fdset(curl_fds);
all_fds = curl_fds;
gui_rpcs.get_fdset(gui_rpc_fds, all_fds);
double_to_timeval(action?0:x, tv);
bool have_async = have_async_file_op();
// prioritize network (including GUI RPC) over async file ops.
// if there's a pending asynch file op, do the select with zero timeout;
// otherwise do it for the remaining amount of time.
double_to_timeval(have_async?0:time_remaining, tv);
#ifdef NEW_CPU_THROTTLE
client_mutex.unlock();
#endif
@ -843,28 +848,24 @@ void CLIENT_STATE::do_io_or_sleep(double x) {
// called pretty often, even if no descriptors are enabled.
// So do the "if (n==0) break" AFTER the got_selects().
http_ops->got_select(all_fds, x);
http_ops->got_select(all_fds, time_remaining);
gui_rpcs.got_select(all_fds);
if (!action && n==0) break;
#if 0
// Limit number of times thru this loop.
// Can get stuck in while loop, if network isn't available,
// DNS lookups tend to eat CPU cycles.
//
if (loops++ > 99) {
boinc_sleep(.01);
#ifdef __EMX__
DosSleep(0);
#endif
break;
if (have_async) {
// do the async file op only if no network activity
//
if (n == 0) {
do_async_file_op();
}
} else {
if (n == 0) {
break;
}
}
#endif
set_now();
if (now > end_time) break;
x = end_time - now;
time_remaining = end_time - now;
}
}