diff --git a/checkin_notes b/checkin_notes index 5e87998f57..1db38761a4 100644 --- a/checkin_notes +++ b/checkin_notes @@ -6926,3 +6926,15 @@ David 19 Nov 2012 lib/ mac_address.cpp,h (removed) + +David 19 Nov 2012 + - client: if a project has 64 or more ready-to-report tasks, + report them. + 64 is chosen a bit arbitrarily, but the idea is to + limit the number of tasks reported per RPC, + and to accelerate the reporting of small tasks. + + client/ + client_state.h + cs_scheduler.cpp + project.h diff --git a/client/client_state.h b/client/client_state.h index 42eba833a9..03c07593ad 100644 --- a/client/client_state.h +++ b/client/client_state.h @@ -543,11 +543,15 @@ extern void print_suspend_tasks_message(int); // we'll find out about it within a day. #define WF_DEFER_INTERVAL 300 - // if a project is uploading, and the last upload started within this interval, + // if a project is uploading, + // and the last upload started within this interval, // don't fetch work from it. // This allows the work fetch to be merged with the reporting of the // jobs that are currently uploading. +#define RESULT_REPORT_IF_AT_LEAST_N 64 + // If a project has at least this many ready-to-report tasks, report them. + //////// CPU SCHEDULING #define CPU_SCHED_PERIOD 60 diff --git a/client/cs_scheduler.cpp b/client/cs_scheduler.cpp index 7400e76ed9..5d24d9e7c4 100644 --- a/client/cs_scheduler.cpp +++ b/client/cs_scheduler.cpp @@ -385,8 +385,8 @@ static inline bool actively_uploading(PROJECT* p) { && (gstate.now - p->last_upload_start < WF_DEFER_INTERVAL); } -// called from the client's polling loop. -// initiate scheduler RPC activity if needed and possible +// Called once/sec. +// Initiate scheduler RPC activity if needed and possible // bool CLIENT_STATE::scheduler_rpc_poll() { PROJECT *p; @@ -394,6 +394,9 @@ bool CLIENT_STATE::scheduler_rpc_poll() { static double last_work_fetch_time = 0; double elapsed_time; + // are we currently doing a scheduler RPC? + // If so, see if it's finished + // if (scheduler_op->state != SCHEDULER_OP_STATE_IDLE) { last_time = now; scheduler_op->poll(); @@ -441,21 +444,9 @@ bool CLIENT_STATE::scheduler_rpc_poll() { return true; } - // report overdue results + // stuff from here on is checked only once/minute, + // or if work fetch was requested. // - bool suspend_soon = global_prefs.net_times.suspended(now + 1800); - suspend_soon |= global_prefs.cpu_times.suspended(now + 1800); - p = find_project_with_overdue_results(suspend_soon); - if (p && !actively_uploading(p)) { - work_fetch.piggyback_work_request(p); - scheduler_op->init_op_project(p, RPC_REASON_RESULTS_DUE); - return true; - } - - // should we check work fetch? Do this at most once/minute - - if (tasks_suspended) return false; - if (config.fetch_minimal_work && had_or_requested_work) return false; if (must_check_work_fetch) { last_work_fetch_time = 0; @@ -465,19 +456,38 @@ bool CLIENT_STATE::scheduler_rpc_poll() { must_check_work_fetch = false; last_work_fetch_time = now; - p = work_fetch.choose_project(true); + // check if we should report finished results + // + bool suspend_soon = global_prefs.net_times.suspended(now + 1800); + suspend_soon |= global_prefs.cpu_times.suspended(now + 1800); + p = find_project_with_overdue_results(suspend_soon); if (p) { - if (actively_uploading(p)) { - if (log_flags.work_fetch_debug) { - msg_printf(p, MSG_INFO, - "[work_fetch] deferring work fetch; upload active" - ); - } - return false; - } - scheduler_op->init_op_project(p, RPC_REASON_NEED_WORK); + work_fetch.piggyback_work_request(p); + scheduler_op->init_op_project(p, RPC_REASON_RESULTS_DUE); return true; } + + // check if we should fetch work. + // + + if (!tasks_suspended + && !(config.fetch_minimal_work && had_or_requested_work) + ) { + + p = work_fetch.choose_project(true); + if (p) { + if (actively_uploading(p)) { + if (log_flags.work_fetch_debug) { + msg_printf(p, MSG_INFO, + "[work_fetch] deferring work fetch; upload active" + ); + } + return false; + } + scheduler_op->init_op_project(p, RPC_REASON_NEED_WORK); + return true; + } + } return false; } @@ -1165,6 +1175,7 @@ PROJECT* CLIENT_STATE::next_project_trickle_up_pending() { // or we have a sporadic connection // or the project is in "don't request more work" state // or a network suspend period is coming up soon +// or the project has > RESULT_REPORT_IF_AT_LEAST_N results ready to report // PROJECT* CLIENT_STATE::find_project_with_overdue_results( bool network_suspend_soon @@ -1172,16 +1183,23 @@ PROJECT* CLIENT_STATE::find_project_with_overdue_results( unsigned int i; RESULT* r; + for (i=0; in_ready = 0; + p->dont_contact = false; + if (p->waiting_until_min_rpc_time()) p->dont_contact = true; + if (p->suspended_via_gui) p->dont_contact = true; +#ifndef SIM + if (actively_uploading(p)) p->dont_contact = true; +#endif + } + for (i=0; iready_to_report) continue; PROJECT* p = r->project; - if (p->waiting_until_min_rpc_time()) continue; - if (p->suspended_via_gui) continue; -#ifndef SIM - if (actively_uploading(p)) continue; -#endif + if (p->dont_contact) continue; if (p->dont_request_more_work) { return p; @@ -1211,6 +1229,11 @@ PROJECT* CLIENT_STATE::find_project_with_overdue_results( if (gstate.now > r->completed_time + SECONDS_PER_DAY) { return p; } + + p->n_ready++; + if (p->n_ready >= RESULT_REPORT_IF_AT_LEAST_N) { + return p; + } } return 0; } diff --git a/client/project.h b/client/project.h index ffc30e1af3..fae18cb1ed 100644 --- a/client/project.h +++ b/client/project.h @@ -270,6 +270,10 @@ struct PROJECT : PROJ_AM { // get scheduler URL with random offset r bool checked; // temporary used when scanning projects + bool dont_contact; + // temp in find_project_with_overdue_results() + int n_ready; + // temp in find_project_with_overdue_results() FILE_XFER_BACKOFF download_backoff; FILE_XFER_BACKOFF upload_backoff;