- client/scheduler: fix a group of bugs related to the new mechanism

where the client tells the scheduler which app versions
    its queued jobs use
    (this is needed, e.g., to enforce per-app or per-resource job limits).
    In this mechanism, the client sends an array of <app_version>s,
    and each <other_result> includes an index into this array.

    - The wrong index was being sent (client).
    - If an <app_version> had a non-existent app name
        (e.g. because that app had been deprecated)
        it wasn't getting put in the array, invalidating array indices
        Furthermore, an erroneous message was being sent to the user

        Fix: if parse error for <app_version>,
        put it in the array anyway, but with cav.app = NULL,
        meaning that it's a place-holder.
        Send a message to user only if anon platform.

- manager: increase notice buffers to 64K

svn path=/trunk/boinc/; revision=22052
This commit is contained in:
David Anderson 2010-07-23 17:43:20 +00:00
parent 5e87d07598
commit 6b8a569d6d
9 changed files with 73 additions and 15 deletions

View File

@ -5546,3 +5546,33 @@ Rom 23 Jul 2010
MainDocument.cpp
sg_BoincSimpleGUI.cpp
sg_ProjectsComponent.h
David 23 Jul 2010
- client/scheduler: fix a group of bugs related to the new mechanism
where the client tells the scheduler which app versions
its queued jobs use
(this is needed, e.g., to enforce per-app or per-resource job limits).
In this mechanism, the client sends an array of <app_version>s,
and each <other_result> includes an index into this array.
- The wrong index was being sent (client).
- If an <app_version> had a non-existent app name
(e.g. because that app had been deprecated)
it wasn't getting put in the array, invalidating array indices
Furthermore, an erroneous message was being sent to the user
Fix: if parse error for <app_version>,
put it in the array anyway, but with cav.app = NULL,
meaning that it's a place-holder.
Send a message to user only if anon platform.
- manager: increase notice buffers to 64K
client/
cs_scheduler.cpp
clientgui/
NoticeListCtrl.cpp
sched/
sched_send.cpp,h
sched_locality.cpp
sched_types.cpp

View File

@ -285,11 +285,12 @@ int CLIENT_STATE::make_scheduler_request(PROJECT* p) {
// send descriptions of app versions
//
fprintf(f, "<app_versions>\n");
int j=0;
for (i=0; i<app_versions.size(); i++) {
APP_VERSION* avp = app_versions[i];
if (avp->project != p) continue;
avp->write(mf, false);
avp->index = i;
avp->index = j++;
}
fprintf(f, "</app_versions>\n");

View File

@ -204,7 +204,7 @@ wxAccStatus CNoticeListCtrlAccessible::GetDescription(int childId, wxString* des
if (pDoc && (childId != wxACC_SELF)) {
strBuffer = wxEmptyString;
char buf[8192];
char buf[65000];
fix_html(pDoc->notice(childId-1)->description.c_str(), buf);
strDescription = process_client_message(buf);
strProjectName = wxString(pDoc->notice(childId-1)->project_name, wxConvUTF8);
@ -549,7 +549,7 @@ wxString CNoticeListCtrl::OnGetItem(size_t i) const
strProjectName = wxString(np->project_name, wxConvUTF8);
strURL = wxString(np->link, wxConvUTF8);
strTitle = wxString(process_client_message(np->title), wxConvUTF8);
char buf[8192];
char buf[65000];
fix_html(np->description.c_str(), buf);
strDescription = process_client_message(buf);

View File

@ -289,7 +289,7 @@ static int possibly_send_result(DB_RESULT& result) {
bavp = get_app_version(wu, true, false);
if (!bavp && anonymous(g_request->platforms.list[0])) {
if (!bavp && is_anonymous(g_request->platforms.list[0])) {
char help_msg_buf[512];
sprintf(help_msg_buf,
"To get more %s work, finish current work, stop BOINC, remove app_info.xml file, and restart.",

View File

@ -1501,7 +1501,7 @@ void send_work_setup() {
g_wreq->seconds_to_fill = clamp_req_sec(g_request->work_req_seconds);
g_wreq->cpu_req_secs = clamp_req_sec(g_request->cpu_req_secs);
g_wreq->cpu_req_instances = g_request->cpu_req_instances;
g_wreq->anonymous_platform = anonymous(g_request->platforms.list[0]);
g_wreq->anonymous_platform = is_anonymous(g_request->platforms.list[0]);
if (g_wreq->anonymous_platform) {
estimate_flops_anon_platform();
@ -1538,13 +1538,18 @@ void send_work_setup() {
OTHER_RESULT& r = g_request->other_results[i];
APP* app = NULL;
bool uses_gpu = false;
bool have_cav = false;
if (r.app_version >= 0
&& r.app_version < (int)g_request->client_app_versions.size()
) {
CLIENT_APP_VERSION& cav = g_request->client_app_versions[r.app_version];
app = cav.app;
uses_gpu = cav.host_usage.uses_gpu();
} else {
if (app) {
have_cav = true;
uses_gpu = cav.host_usage.uses_gpu();
}
}
if (!have_cav) {
if (r.have_plan_class && app_plan_uses_gpu(r.plan_class)) {
uses_gpu = true;
}

View File

@ -30,7 +30,7 @@ extern int add_result_to_reply(
bool locality_scheduling
);
inline bool anonymous(PLATFORM* platform) {
inline bool is_anonymous(PLATFORM* platform) {
return (!strcmp(platform->name, "anonymous"));
}

View File

@ -88,6 +88,7 @@ int CLIENT_APP_VERSION::parse(FILE* f) {
}
if (parse_double(buf, "<flops>", x)) {
if (x>0) host_usage.projected_flops = x;
continue;
}
if (match_tag(buf, "<coproc>")) {
COPROC_REQ coproc_req;
@ -100,6 +101,7 @@ int CLIENT_APP_VERSION::parse(FILE* f) {
if (!retval && !strcmp(coproc_req.type, "ATI")) {
host_usage.natis = coproc_req.count;
}
continue;
}
}
return ERR_XML_PARSE;
@ -260,13 +262,29 @@ const char* SCHEDULER_REQUEST::parse(FILE* fin) {
CLIENT_APP_VERSION cav;
retval = cav.parse(fin);
if (retval) {
g_reply->insert_message(
"Invalid app version description in app_info.xml",
"notice"
);
} else {
client_app_versions.push_back(cav);
if (is_anonymous(platforms.list[0])) {
if (retval == ERR_NOT_FOUND) {
g_reply->insert_message(
_("Unknown app name in app_info.xml"),
"notice"
);
} else {
g_reply->insert_message(
_("Syntax error in app_info.xml"),
"notice"
);
}
} else {
// this case happens if the app version
// refers to a deprecated app
}
cav.app = 0;
}
// store the CLIENT_APP_VERSION even if it didn't parse.
// This is necessary to maintain the correspondence
// with result.app_version
//
client_app_versions.push_back(cav);
}
}
continue;
@ -474,7 +492,7 @@ int SCHEDULER_REQUEST::write(FILE* fout) {
prrs_fraction,
cpu_estimated_delay,
code_sign_key,
anonymous(platforms.list[0])?"true":"false"
is_anonymous(platforms.list[0])?"true":"false"
);
for (i=0; i<client_app_versions.size(); i++) {

View File

@ -147,6 +147,8 @@ struct CLIENT_APP_VERSION {
// to reflect the discrepancy between how fast the client
// thinks the app is versus how fast we think it is
APP* app;
// if NULL, this record is a place-holder,
// used to preserve array indices
int parse(FILE*);
};

View File

@ -161,6 +161,7 @@ CLIENT_APP_VERSION* get_app_version_anonymous(APP& app, bool reliable_only) {
}
for (i=0; i<g_request->client_app_versions.size(); i++) {
CLIENT_APP_VERSION& cav = g_request->client_app_versions[i];
if (!cav.app) continue;
if (cav.app->id != app.id) {
continue;
}
@ -255,6 +256,7 @@ void estimate_flops_anon_platform() {
unsigned int i;
for (i=0; i<g_request->client_app_versions.size(); i++) {
CLIENT_APP_VERSION& cav = g_request->client_app_versions[i];
if (!cav.app) continue;
cav.rsc_fpops_scale = 1;