boinc/db/boinc_db.h

535 lines
14 KiB
C
Raw Normal View History

// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2008 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// BOINC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
#ifndef _BOINC_DB_
#define _BOINC_DB_
// Structures corresponding to database records.
// Some of these types have counterparts in client/types.h,
// but don't be deceived - client and server have different variants.
// The parse and write functions are for use in scheduler RPC.
// They don't necessarily serialize the entire records.
#include <cstdio>
#include <vector>
2010-04-21 20:11:41 +00:00
#include <string.h>
#include "db_base.h"
#include "boinc_db_types.h"
extern DB_CONN boinc_db;
struct TRANSITIONER_ITEM {
int id; // WARNING: this is the WU ID
char name[256];
int appid;
int min_quorum;
bool need_validate;
int canonical_resultid;
int transition_time;
int delay_bound;
int error_mask;
int max_error_results;
int max_total_results;
int file_delete_state;
int assimilate_state;
int target_nresults;
char result_template_file[64];
int priority;
int hr_class;
int batch;
int app_version_id;
int transitioner_flags;
int size_class;
int res_id; // This is the RESULT ID
char res_name[256];
int res_report_deadline;
int res_server_state;
int res_outcome;
int res_validate_state;
int res_file_delete_state;
int res_sent_time;
int res_hostid;
int res_received_time;
int res_app_version_id;
int res_exit_status;
void clear();
void parse(MYSQL_ROW&);
};
struct DB_HOST_APP_VERSION : public DB_BASE, public HOST_APP_VERSION {
DB_HOST_APP_VERSION(DB_CONN* p=0);
void db_print(char*);
void db_parse(MYSQL_ROW &row);
- server: change the following from per-host to per-(host, app version): - daily quota mechanism - reliable mechanism (accelerated retries) - "trusted" mechanism (adaptive replication) - scheduler: enforce host scale probation only for apps with host_scale_check set. - validator: do scale probation on invalid results (need this in addition to error and timeout cases) - feeder: update app version scales every 10 min, not 10 sec - back-end apps: support --foo as well as -foo for options Notes: - If you have, say, cuda, cuda23 and cuda_fermi plan classes, a host will have separate quotas for each one. That means it could error out on 100 jobs for cuda_fermi, and when its quota goes to zero, error out on 100 jobs for cuda23, etc. This is intentional; there may be cases where one version works but not the others. - host.error_rate and host.max_results_day are deprecated TODO: - the values in the app table for limits on jobs in progress etc. should override rather than config.xml. Implementation notes: scheduler: process_request(): read all host_app_versions for host at start; Compute "reliable" and "trusted" for each one. write modified records at end get_app_version(): add "reliable_only" arg; if set, use only reliable versions skip over-quota versions Multi-pass scheduling: if have at least one reliable version, do a pass for jobs that need reliable, and use only reliable versions. Then clear best_app_versions cache. Score-based scheduling: for need-reliable jobs, it will pick the fastest version, then give a score bonus if that version happens to be reliable. When get back a successful result from client: increase daily quota When get back an error result from client: impose scale probation decrease daily quota if not aborted Validator: when handling a WU, create a vector of HOST_APP_VERSION parallel to vector of RESULT. Pass it to assign_credit_set(). Make copies of originals so we can update only modified ones update HOST_APP_VERSION error rates Transitioner: decrease quota on timeout svn path=/trunk/boinc/; revision=21181
2010-04-15 03:13:56 +00:00
int update_scheduler(DB_HOST_APP_VERSION&);
int update_validator(DB_HOST_APP_VERSION&);
};
struct DB_USER_SUBMIT : public DB_BASE, public USER_SUBMIT {
DB_USER_SUBMIT(DB_CONN* p=0);
void db_print(char*);
void db_parse(MYSQL_ROW &row);
};
struct STATE_COUNTS {
int appid;
int last_update_time;
int result_server_state_2;
int result_server_state_4;
int result_file_delete_state_1;
int result_file_delete_state_2;
int result_server_state_5_and_file_delete_state_0;
int workunit_need_validate_1;
int workunit_assimilate_state_1;
int workunit_file_delete_state_1;
int workunit_file_delete_state_2;
void clear();
};
struct DB_STATE_COUNTS : public DB_BASE, public STATE_COUNTS {
DB_STATE_COUNTS(DB_CONN* p=0);
int get_id();
void db_print(char *);
void db_parse(MYSQL_ROW &row);
};
struct VALIDATOR_ITEM {
WORKUNIT wu;
RESULT res;
void clear();
void parse(MYSQL_ROW&);
};
class DB_PLATFORM : public DB_BASE, public PLATFORM {
public:
DB_PLATFORM(DB_CONN* p=0);
int get_id();
void db_print(char*);
void db_parse(MYSQL_ROW &row);
};
class DB_APP : public DB_BASE, public APP {
public:
DB_APP(DB_CONN* p=0);
int get_id();
void db_print(char*);
void db_parse(MYSQL_ROW &row);
};
class DB_APP_VERSION : public DB_BASE, public APP_VERSION {
public:
DB_APP_VERSION(DB_CONN* p=0);
int get_id();
void db_print(char*);
void db_parse(MYSQL_ROW &row);
void operator=(APP_VERSION& w) {APP_VERSION::operator=(w);}
};
class DB_USER : public DB_BASE, public USER {
public:
DB_USER(DB_CONN* p=0);
int get_id();
void db_print(char*);
void db_parse(MYSQL_ROW &row);
void operator=(USER& r) {USER::operator=(r);}
};
class DB_TEAM : public DB_BASE, public TEAM {
public:
DB_TEAM(DB_CONN* p=0);
int get_id();
void db_print(char*);
void db_parse(MYSQL_ROW &row);
};
class DB_HOST : public DB_BASE, public HOST {
public:
DB_HOST(DB_CONN* p=0);
int get_id();
int update_diff_sched(HOST&);
int update_diff_validator(HOST&);
int fpops_percentile(double percentile, double& fpops);
// return the given percentile of p_fpops
int fpops_mean(double& mean);
int fpops_stddev(double& stddev);
void db_print(char*);
void db_parse(MYSQL_ROW &row);
void operator=(HOST& r) {HOST::operator=(r);}
};
class DB_RESULT : public DB_BASE, public RESULT {
public:
DB_RESULT(DB_CONN* p=0);
int get_id();
int mark_as_sent(int old_server_state, int report_grace_period);
void db_print(char*);
void db_print_values(char*);
void db_parse(MYSQL_ROW &row);
void operator=(RESULT& r) {RESULT::operator=(r);}
int get_unsent_counts(APP&, int* unsent);
int make_unsent(
APP&, int size_class, int n, const char* order_clause, int& nchanged
);
};
class DB_WORKUNIT : public DB_BASE, public WORKUNIT {
public:
DB_WORKUNIT(DB_CONN* p=0);
int get_id();
void db_print(char*);
void db_print_values(char*);
void db_parse(MYSQL_ROW &row);
void operator=(WORKUNIT& w) {WORKUNIT::operator=(w);}
};
2007-05-02 23:17:52 +00:00
class DB_CREDITED_JOB : public DB_BASE, public CREDITED_JOB {
2007-05-02 18:51:51 +00:00
public:
2007-05-02 23:17:52 +00:00
DB_CREDITED_JOB(DB_CONN* p=0);
2007-05-02 18:51:51 +00:00
void db_print(char*);
void db_parse(MYSQL_ROW &row);
2007-05-02 23:17:52 +00:00
void operator=(CREDITED_JOB& wh) {CREDITED_JOB::operator=(wh);}
2007-05-02 18:51:51 +00:00
};
class DB_MSG_FROM_HOST : public DB_BASE, public MSG_FROM_HOST {
public:
DB_MSG_FROM_HOST(DB_CONN* p=0);
int get_id();
void db_print(char*);
void db_parse(MYSQL_ROW &row);
};
class DB_MSG_TO_HOST : public DB_BASE, public MSG_TO_HOST {
public:
DB_MSG_TO_HOST(DB_CONN* p=0);
int get_id();
void db_print(char*);
void db_parse(MYSQL_ROW &row);
};
class DB_ASSIGNMENT : public DB_BASE, public ASSIGNMENT {
public:
DB_ASSIGNMENT(DB_CONN* p=0);
int get_id();
void db_print(char*);
void db_parse(MYSQL_ROW& row);
};
// The transitioner uses this to get (WU, result) pairs efficiently.
// Each call to enumerate() returns a list of the pairs for a single WU
//
class DB_TRANSITIONER_ITEM_SET : public DB_BASE_SPECIAL {
public:
DB_TRANSITIONER_ITEM_SET(DB_CONN* p=0);
TRANSITIONER_ITEM last_item;
int nitems_this_query;
int enumerate(
int transition_time,
int nresult_limit,
int wu_id_modulus,
int wu_id_remainder,
std::vector<TRANSITIONER_ITEM>& items
);
int update_result(TRANSITIONER_ITEM&);
int update_workunit(TRANSITIONER_ITEM&, TRANSITIONER_ITEM&);
};
// The validator uses this to get (WU, result) pairs efficiently.
// Each call to enumerate() returns a list of the pairs for a single WU
//
class DB_VALIDATOR_ITEM_SET : public DB_BASE_SPECIAL {
public:
DB_VALIDATOR_ITEM_SET(DB_CONN* p=0);
VALIDATOR_ITEM last_item;
int nitems_this_query;
int enumerate(
int appid,
int nresult_limit,
int wu_id_modulus,
int wu_id_remainder,
int wu_id_min,
int wu_id_max,
std::vector<VALIDATOR_ITEM>& items
);
int update_result(RESULT&);
int update_workunit(WORKUNIT&);
};
// used by the feeder and scheduler for outgoing work
//
struct WORK_ITEM {
int res_id;
int res_priority;
int res_server_state;
double res_report_deadline;
WORKUNIT wu;
void parse(MYSQL_ROW& row);
};
class DB_WORK_ITEM : public WORK_ITEM, public DB_BASE_SPECIAL {
int start_id;
// when enumerate_all is used, keeps track of which ID to start from
public:
DB_WORK_ITEM(DB_CONN* p=0);
int enumerate(
int limit, const char* select_clause, const char* order_clause
);
// used by feeder
int enumerate_all(
int limit, const char* select_clause
);
// used by feeder when HR is used.
// Successive calls cycle through all results.
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 to send <result_abort> or <result_abort_if_not_started>
// messages if the result is no longer needed.
//
struct IN_PROGRESS_RESULT {
char result_name[256];
int assimilate_state;
int error_mask;
int server_state;
int outcome;
void parse(MYSQL_ROW& row);
};
class DB_IN_PROGRESS_RESULT : public IN_PROGRESS_RESULT, public DB_BASE_SPECIAL {
public:
DB_IN_PROGRESS_RESULT(DB_CONN* p=0);
int enumerate(int hostid, const char* result_names);
};
// Used by the scheduler to handle results reported by clients
// The read and the update of these results are combined
// into single SQL queries.
struct SCHED_RESULT_ITEM {
char queried_name[256]; // name as reported by client
int id;
char name[256];
int workunitid;
int appid;
int server_state;
int client_state;
int validate_state;
int outcome;
int hostid;
int userid;
int teamid;
int sent_time;
int received_time;
double cpu_time;
char xml_doc_out[BLOB_SIZE];
char stderr_out[BLOB_SIZE];
int app_version_num;
int exit_status;
int file_delete_state;
double elapsed_time;
- server: change the following from per-host to per-(host, app version): - daily quota mechanism - reliable mechanism (accelerated retries) - "trusted" mechanism (adaptive replication) - scheduler: enforce host scale probation only for apps with host_scale_check set. - validator: do scale probation on invalid results (need this in addition to error and timeout cases) - feeder: update app version scales every 10 min, not 10 sec - back-end apps: support --foo as well as -foo for options Notes: - If you have, say, cuda, cuda23 and cuda_fermi plan classes, a host will have separate quotas for each one. That means it could error out on 100 jobs for cuda_fermi, and when its quota goes to zero, error out on 100 jobs for cuda23, etc. This is intentional; there may be cases where one version works but not the others. - host.error_rate and host.max_results_day are deprecated TODO: - the values in the app table for limits on jobs in progress etc. should override rather than config.xml. Implementation notes: scheduler: process_request(): read all host_app_versions for host at start; Compute "reliable" and "trusted" for each one. write modified records at end get_app_version(): add "reliable_only" arg; if set, use only reliable versions skip over-quota versions Multi-pass scheduling: if have at least one reliable version, do a pass for jobs that need reliable, and use only reliable versions. Then clear best_app_versions cache. Score-based scheduling: for need-reliable jobs, it will pick the fastest version, then give a score bonus if that version happens to be reliable. When get back a successful result from client: increase daily quota When get back an error result from client: impose scale probation decrease daily quota if not aborted Validator: when handling a WU, create a vector of HOST_APP_VERSION parallel to vector of RESULT. Pass it to assign_credit_set(). Make copies of originals so we can update only modified ones update HOST_APP_VERSION error rates Transitioner: decrease quota on timeout svn path=/trunk/boinc/; revision=21181
2010-04-15 03:13:56 +00:00
int app_version_id;
double peak_working_set_size;
double peak_swap_size;
double peak_disk_usage;
void clear();
void parse(MYSQL_ROW& row);
};
class DB_SCHED_RESULT_ITEM_SET : public DB_BASE_SPECIAL {
public:
DB_SCHED_RESULT_ITEM_SET(DB_CONN* p=0);
std::vector<SCHED_RESULT_ITEM> results;
int add_result(char* result_name);
int enumerate();
// using a single SQL query, look up all the reported results,
// (based on queried_name)
// and fill in the rest of the entries in the results vector
int lookup_result(char* result_name, SCHED_RESULT_ITEM** result);
int update_result(SCHED_RESULT_ITEM& result);
int update_workunits();
};
struct FILE_ITEM {
int id;
char name[254];
char md5sum[34];
double size;
void clear();
};
class DB_FILE : public DB_BASE, public FILE_ITEM {
public:
DB_FILE(DB_CONN* p=0);
int get_id();
void db_print(char*);
void db_parse(MYSQL_ROW &row);
void operator=(FILE_ITEM& f) {FILE_ITEM::operator=(f);}
};
struct FILESET_ITEM {
int id;
char name[254];
void clear();
};
class DB_FILESET : public DB_BASE, public FILESET_ITEM {
public:
DB_FILESET(DB_CONN* p=0);
int get_id();
void db_print(char*);
void db_parse(MYSQL_ROW &row);
void operator=(FILESET_ITEM& f) {FILESET_ITEM::operator=(f);}
// retrieve fileset instance (populate object)
int select_by_name(const char* name);
};
struct FILESET_FILE_ITEM {
int fileset_id;
int file_id;
void clear();
};
class DB_FILESET_FILE : public DB_BASE, public FILESET_FILE_ITEM {
public:
DB_FILESET_FILE(DB_CONN* p=0);
void db_print(char*);
void db_parse(MYSQL_ROW &row);
void operator=(FILESET_FILE_ITEM& tf) {FILESET_FILE_ITEM::operator=(tf);}
};
struct SCHED_TRIGGER_ITEM {
int id;
int fileset_id;
bool need_work;
bool work_available;
bool no_work_available;
bool working_set_removal;
void clear();
};
class DB_SCHED_TRIGGER : public DB_BASE, public SCHED_TRIGGER_ITEM {
public:
DB_SCHED_TRIGGER(DB_CONN* p=0);
int get_id();
void db_print(char*);
void db_parse(MYSQL_ROW &row);
void operator=(SCHED_TRIGGER_ITEM& t) {SCHED_TRIGGER_ITEM::operator=(t);}
typedef enum {
none = 0,
state_need_work = 1,
state_work_available = 2,
state_no_work_available = 3,
state_working_set_removal = 4
} STATE;
// retrieve trigger instance (populate object)
int select_unique_by_fileset_name(const char* fileset_name);
// set single trigger state
int update_single_state(const DB_SCHED_TRIGGER::STATE state, const bool value);
};
struct FILESET_SCHED_TRIGGER_ITEM {
FILESET_ITEM fileset;
SCHED_TRIGGER_ITEM trigger;
void clear();
};
class DB_FILESET_SCHED_TRIGGER_ITEM : public DB_BASE_SPECIAL, public FILESET_SCHED_TRIGGER_ITEM {
public:
DB_FILESET_SCHED_TRIGGER_ITEM(DB_CONN* p=0);
void db_parse(MYSQL_ROW &row);
void operator=(FILESET_SCHED_TRIGGER_ITEM& fst) {FILESET_SCHED_TRIGGER_ITEM::operator=(fst);}
};
class DB_FILESET_SCHED_TRIGGER_ITEM_SET : public DB_BASE_SPECIAL {
public:
DB_FILESET_SCHED_TRIGGER_ITEM_SET(DB_CONN* p=0);
// select available triggers based on name and/or state
// -> name filter optional (set string, default NULL)
// -> pattern search optional (set use_regexp to true, default false))
// -> state filter optional (set state, default none)
// -> state_value (default true)
int select_by_name_state(
const char* fileset_name,
const bool use_regexp,
const DB_SCHED_TRIGGER::STATE state,
const bool state_value);
// check if given trigger (fileset name) is part of set and return position (1-indexed)
int contains_trigger(const char* fileset_name);
// storage vector
std::vector<DB_FILESET_SCHED_TRIGGER_ITEM> items;
};
struct DB_VDA_FILE : public DB_BASE, public VDA_FILE {
DB_VDA_FILE(DB_CONN* p=0);
int get_id();
void db_print(char*);
void db_parse(MYSQL_ROW &row);
};
struct DB_VDA_CHUNK_HOST : public DB_BASE, public VDA_CHUNK_HOST {
DB_VDA_CHUNK_HOST(DB_CONN* p=0);
void db_print(char*);
void db_parse(MYSQL_ROW &row);
};
struct DB_BADGE : public DB_BASE, public BADGE {
DB_BADGE(DB_CONN* p=0);
int get_id() {return id;};
void db_print(char*){};
void db_parse(MYSQL_ROW&);
};
struct DB_BADGE_USER : public DB_BASE, public BADGE_USER {
DB_BADGE_USER(DB_CONN* p=0);
void db_print(char*){};
void db_parse(MYSQL_ROW&);
};
struct DB_BADGE_TEAM : public DB_BASE, public BADGE_TEAM {
DB_BADGE_TEAM(DB_CONN* p=0);
void db_print(char*){};
void db_parse(MYSQL_ROW&);
};
#endif