diff --git a/checkin_notes b/checkin_notes index 882bbc689f..9a232de008 100755 --- a/checkin_notes +++ b/checkin_notes @@ -14532,3 +14532,16 @@ Daniel 2004-07-02 api.php compound_app.php +David 2 July 2004 + - added new classes DB_RESULT_DONE, DB_WORK_ITEM, DB_ACCOUNT_INFO + for efficient DB access + - feeder: don't need to check server state because scheduler also checks + - sched_config.parse(): if db host is current host, substitute "localhost" + + db/ + boinc_db.C,h + sched/ + feeder.C + sched_config.C + tools/ + create_work.C diff --git a/db/boinc_db.C b/db/boinc_db.C index 222f75e49b..f62fc5eef1 100644 --- a/db/boinc_db.C +++ b/db/boinc_db.C @@ -61,6 +61,7 @@ DB_RESULT::DB_RESULT() : DB_BASE(boinc_db, "result"){} DB_MSG_FROM_HOST::DB_MSG_FROM_HOST() : DB_BASE(boinc_db, "msg_from_host"){} DB_MSG_TO_HOST::DB_MSG_TO_HOST() : DB_BASE(boinc_db, "msg_to_host"){} DB_TRANSITIONER_ITEM_SET::DB_TRANSITIONER_ITEM_SET() : DB_BASE_SPECIAL(boinc_db){} +DB_WORK_ITEM::DB_WORK_ITEM() : DB_BASE_SPECIAL(boinc_db){} int DB_PLATFORM::get_id() {return id;} int DB_CORE_VERSION::get_id() {return id;} @@ -721,3 +722,84 @@ int DB_TRANSITIONER_ITEM_SET::update_workunit(TRANSITIONER_ITEM& ti) { ); return db->do_query(query); } + +void WORK_ITEM::parse(MYSQL_ROW& r) { + int i=0; + memset(this, 0, sizeof(WORK_ITEM)); + res_id = atoi(r[i++]); + strcpy2(res_xml_doc_in, r[i++]); + workunitid = atoi(r[i++]); + wu_rsc_memory_bound = atof(r[i++]); + wu_delay_bound = atof(r[i++]); + wu_rsc_fpops_est = atof(r[i++]); + wu_rsc_fpops_bound = atof(r[i++]); + wu_rsc_disk_bound = atof(r[i++]); + strcpy2(wu_name, r[i++]); + strcpy2(wu_xml_doc, r[i++]); +} + +int DB_WORK_ITEM::enumerate(char* clause) { + char query[MAX_QUERY_LEN]; + int retval; + MYSQL_ROW row; + + if (!cursor.active) { + sprintf(query, + "select result.id as res_id, " + "result.xml_doc_in as res_xml_doc_in, " + "result.workunit as workunitid, " + "workunit.rsc_memory_bound as wu_rsc_memory_bound, " + "workunit.delay_bound as wu_delay_bound, " + "workunit.rsc_fpops_set as wu_rsc_fpops_set, " + "workunit.rsc_fpops_bound as wu_rsc_fpops_bound, " + "workunit.rsc_disk_bound as wu_rsc_disk_bound, " + "workunit.name as wu_name, " + "workunit.xml_doc as wu_xml_doc " + "from result, workunit " + "where workunit.id = result.id %s", + clause + ); + retval = db->do_query(query); + if (retval) return mysql_errno(db->mysql); + cursor.rp = mysql_store_result(db->mysql); + if (!cursor.rp) return mysql_errno(db->mysql); + } + row = mysql_fetch_row(cursor.rp); + if (!row) { + mysql_free_result(cursor.rp); + cursor.active = false; + return 1; + } else { + parse(row); + } + return 0; +} + +int DB_WORK_ITEM::read_result() { + char query[MAX_QUERY_LEN]; + int retval; + MYSQL_RES* rp; + MYSQL_ROW row; + + sprintf(query, "select server_state from result where id=%d", res_id); + retval = db->do_query(query); + rp = mysql_store_result(db->mysql); + if (!rp) { + return mysql_errno(db->mysql); + } + row = mysql_fetch_row(rp); + if (!row) { + return mysql_errno(db->mysql); + } + res_server_state = atoi(row[0]); + return 0; +} + +int DB_WORK_ITEM::update() { + char query[MAX_QUERY_LEN]; + + sprintf(query, "update workunit set transition_time=%f where id=%d", + wu_transition_time, workunitid + ); + return db->do_query(query); +} diff --git a/db/boinc_db.h b/db/boinc_db.h index bedfaf8561..7435d87a85 100755 --- a/db/boinc_db.h +++ b/db/boinc_db.h @@ -585,6 +585,77 @@ public: int update_workunit(TRANSITIONER_ITEM&); }; +// used by the feeder and scheduler for outgoing work +// +struct WORK_ITEM { + int res_id; + int res_server_state; + char res_xml_doc_in[LARGE_BLOB_SIZE]; + int workunitid; + double wu_rsc_memory_bound; + double wu_delay_bound; + double wu_rsc_fpops_est; + double wu_rsc_fpops_bound; + double wu_rsc_disk_bound; + double wu_transition_time; + char wu_name[256]; + char wu_xml_doc[LARGE_BLOB_SIZE]; + void parse(MYSQL_ROW& row); +}; + +class DB_WORK_ITEM : public WORK_ITEM, public DB_BASE_SPECIAL { +public: + DB_WORK_ITEM(); + CURSOR cursor; + int enumerate(char* clause); + // used by feeder + int read_result(); + // used by scheduler to read result server state + int update(); + // used by scheduler to update WU transition time + // and various result fields +}; + +// used by the scheduler for handling completed results +// +class DB_RESULT_DONE : public DB_BASE_SPECIAL { +public: + DB_RESULT_DONE(); + int hostid; + int received_time; + int client_state; + int cpu_time; + int exit_status; + int claimed_credit; + int teamid; + int workunitid; + char stderr_out[LARGE_BLOB_SIZE]; + char xml_doc_out[LARGE_BLOB_SIZE]; + + int lookup(); + // lookup by name; reads hostid, server_state, workunitid + int update(); + // updates all fields except hostid, workunitid + // sets transition time of corresponding WU +}; + +// used by the scheduler for looking up and updating host/user/team +// +class DB_ACCOUNT_INFO : public DB_BASE_SPECIAL { + DB_ACCOUNT_INFO(); + HOST host; + USER user; + TEAM team; + + int lookup_hostid(); + // used when hostid is supplied; reads all 3 records + int lookup_auth(); + // used when no hostid is supplied; reads user/team + // must manually create host + // no update functions here because we always update the entire host, + // and we update the entire user infrequently +}; + #if 0 class DB_WORKSEQ : public DB_BASE, public WORKSEQ { public: diff --git a/sched/feeder.C b/sched/feeder.C index dfaaf99358..29b54c1884 100644 --- a/sched/feeder.C +++ b/sched/feeder.C @@ -215,6 +215,10 @@ try_again: } } +#if 0 + // We don't need to do the following because the + // scheduler makes this check also + // // there's a chance this result was sent out // after the enumeration started. // So read it from the DB again @@ -234,6 +238,7 @@ try_again: ); goto try_again; } +#endif collision = false; for (j=0; jnwu_results; j++) { if (ssp->wu_results[j].state != WR_STATE_EMPTY diff --git a/sched/sched_config.C b/sched/sched_config.C index d9eb088671..2fb610aaf9 100644 --- a/sched/sched_config.C +++ b/sched/sched_config.C @@ -65,7 +65,12 @@ int SCHED_CONFIG::parse(char* buf) { parse_int(buf, "", min_sendwork_interval); parse_int(buf, "", max_wus_to_send); parse_int(buf, "", daily_result_quota); - if (match_tag(buf, "")) return 0; + if (match_tag(buf, "")) { + char hostname[256]; + gethostname(hostname, 256); + if (!strcmp(hostname, db_host)) strcpy(db_host, "localhost"); + return 0; + } return ERR_XML_PARSE; } diff --git a/tools/create_work.C b/tools/create_work.C index f9e91ac05c..97c835b87b 100644 --- a/tools/create_work.C +++ b/tools/create_work.C @@ -156,8 +156,9 @@ int main(int argc, char** argv) { #undef CHKARG #undef CHKARG_STR - if (boinc_db.open(db_name, db_host, db_user, db_passwd)) { - fprintf(stderr, "create_work: error opening database.\n" ); + retval = boinc_db.open(db_name, db_host, db_user, db_passwd); + if (retval) { + fprintf(stderr, "create_work: error opening database: %d\n", retval ); exit(1); } sprintf(buf, "where name='%s'", app.name);