📄 validator.c
字号:
"[RESULT#%d %s] granted_credit %f\n", result.id, result.name, result.granted_credit ); retval = validator.update_result(result); if (retval) { log_messages.printf( SCHED_MSG_LOG::MSG_CRITICAL, "[RESULT#%d %s] Can't update result: %d\n", result.id, result.name, retval ); } } } } else { vector<RESULT> results; int nsuccess_results; // Here if WU doesn't have a canonical result yet. // Try to get one log_messages.printf( SCHED_MSG_LOG::MSG_NORMAL, "[WU#%d %s] handle_wu(): No canonical result yet\n", wu.id, wu.name ); ++log_messages; // make a vector of only successful results // for (i=0; i<items.size(); i++) { RESULT& result = items[i].res; if ((result.server_state == RESULT_SERVER_STATE_OVER) && (result.outcome == RESULT_OUTCOME_SUCCESS) ) { results.push_back(result); } } log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[WU#%d %s] Found %d successful results\n", wu.id, wu.name, (int)results.size() ); if (results.size() >= (unsigned int)wu.min_quorum) { log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[WU#%d %s] Enough for quorum, checking set.\n", wu.id, wu.name ); retval = check_set(results, wu, canonicalid, credit, retry); if (retval) { log_messages.printf( SCHED_MSG_LOG::MSG_CRITICAL, "[WU#%d %s] check_set returned %d, exiting\n", wu.id, wu.name, retval ); return retval; } if (retry) transition_time = DELAYED; if (credit_from_wu) { credit = get_credit_from_wu(wu, results); } // scan results. // update as needed, and count the # of results // that are still outcome=SUCCESS // (some may have changed to VALIDATE_ERROR) // nsuccess_results = 0; for (i=0; i<results.size(); i++) { update_result = false; RESULT& result = results[i]; if (result.outcome == RESULT_OUTCOME_VALIDATE_ERROR) { transition_time = IMMEDIATE; update_result = true; } else { nsuccess_results++; } switch (result.validate_state) { case VALIDATE_STATE_VALID: // grant credit for valid results // update_result = true; result.granted_credit = grant_claimed_credit ? result.claimed_credit : credit; if (max_granted_credit && result.granted_credit > max_granted_credit) { result.granted_credit = max_granted_credit; } retval = is_valid(result,wu); if (retval) { log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[RESULT#%d %s] is_valid() failed: %d\n", result.id, result.name, retval ); } log_messages.printf( SCHED_MSG_LOG::MSG_NORMAL, "[RESULT#%d %s] Granted %f credit to valid result [HOST#%d]\n", result.id, result.name, result.granted_credit, result.hostid ); break; case VALIDATE_STATE_INVALID: is_invalid(result); update_result = true; break; case VALIDATE_STATE_INIT: result.validate_state = VALIDATE_STATE_INCONCLUSIVE; update_result = true; break; } if (update_result) { retval = validator.update_result(result); if (retval) { log_messages.printf( SCHED_MSG_LOG::MSG_CRITICAL, "[RESULT#%d %s] result.update() failed: %d\n", result.id, result.name, retval ); } } } if (canonicalid) { // if we found a canonical result, // trigger the assimilator, but do NOT trigger // the transitioner - doing so creates a race condition // transition_time = NEVER; log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, "[WU#%d %s] Found a canonical result: id=%d\n", wu.id, wu.name, canonicalid ); wu.canonical_resultid = canonicalid; wu.canonical_credit = credit; wu.assimilate_state = ASSIMILATE_READY; // If found a canonical result, don't send any unsent results // for (i=0; i<items.size(); i++) { RESULT& result = items[i].res; if (result.server_state != RESULT_SERVER_STATE_UNSENT) { continue; } result.server_state = RESULT_SERVER_STATE_OVER; result.outcome = RESULT_OUTCOME_DIDNT_NEED; retval = validator.update_result(result); if (retval) { log_messages.printf( SCHED_MSG_LOG::MSG_CRITICAL, "[RESULT#%d %s] result.update() failed: %d\n", result.id, result.name, retval ); } } } else { // here if no consensus. // check if #success results is too large // if (nsuccess_results > wu.max_success_results) { wu.error_mask |= WU_ERROR_TOO_MANY_SUCCESS_RESULTS; transition_time = IMMEDIATE; } // if #success results == than target_nresults, // we need more results, so bump target_nresults // NOTE: nsuccess_results should never be > target_nresults, // but accommodate that if it should happen // if (nsuccess_results >= wu.target_nresults) { wu.target_nresults = nsuccess_results+1; transition_time = IMMEDIATE; } } } } --log_messages; switch (transition_time) { case IMMEDIATE: wu.transition_time = time(0); break; case DELAYED: x = time(0) + 6*3600; if (x < wu.transition_time) wu.transition_time = x; break; case NEVER: wu.transition_time = INT_MAX; break; case NO_CHANGE: break; } wu.need_validate = 0; retval = validator.update_workunit(wu); if (retval) { log_messages.printf( SCHED_MSG_LOG::MSG_CRITICAL, "[WU#%d %s] update_workunit() failed: %d; exiting\n", wu.id, wu.name, retval ); return retval; } return 0;}// make one pass through the workunits with need_validate set.// return true if there were any//bool do_validate_scan(APP& app) { DB_VALIDATOR_ITEM_SET validator; std::vector<VALIDATOR_ITEM> items; bool found=false; int retval; // loop over entries that need to be checked // while (1) { retval = validator.enumerate( app.id, one_pass_N_WU?one_pass_N_WU:SELECT_LIMIT, wu_id_modulus, wu_id_remainder, items ); if (retval) break; retval = handle_wu(validator, items); if (!retval) found = true; } return found;}int main_loop() { int retval; DB_APP app; bool did_something; char buf[256]; retval = boinc_db.open(config.db_name, config.db_host, config.db_user, config.db_passwd); if (retval) { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "boinc_db.open failed: %d\n", retval); exit(1); } sprintf(buf, "where name='%s'", app_name); retval = app.lookup(buf); if (retval) { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "can't find app %s\n", app_name); exit(1); } while (1) { check_stop_daemons(); did_something = do_validate_scan(app); if (!did_something) { if (one_pass) break; sleep(sleep_interval); } } return 0;}// For use by user routines check_set() and check_match() that link to// this code.int boinc_validator_debuglevel=0;int main(int argc, char** argv) { int i, retval;#if 0 int mypid=getpid(); char debugcmd[512]; sprintf(debugcmd, "ddd %s %d &", argv[0], mypid); system(debugcmd); sleep(30);#endif const char *usage = "\nUsage: %s -app <app-name> [OPTIONS]\n" "Start validator for application <app-name>\n\n" "Optional arguments:\n" " -one_pass_N_WU N Validate at most N WUs, then exit\n" " -one_pass Make one pass through WU table, then exit\n" " -mod n i Process only WUs with (id mod n) == i\n" " -max_claimed_credit X If a result claims more credit than this, mark it as invalid\n" " -max_granted_credit X Grant no more than this amount of credit to a result\n" " -grant_claimed_credit Grant the claimed credit, regardless of what other results for this workunit claimed\n" " -update_credited_job Add record to credited_job table after granting credit\n" " -credit_from_wu Credit is specified in WU XML\n" " -sleep_interval n Set sleep-interval to n\n" " -d level Set debug-level\n\n"; if ( (argc > 1) && ( !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help") ) ) { printf (usage, argv[0] ); exit(1); } check_stop_daemons(); for (i=1; i<argc; i++) { if (!strcmp(argv[i], "-one_pass_N_WU")) { one_pass_N_WU = atoi(argv[++i]); one_pass = true; } else if (!strcmp(argv[i], "-sleep_interval")) { sleep_interval = atoi(argv[++i]); } else if (!strcmp(argv[i], "-one_pass")) { one_pass = true; } else if (!strcmp(argv[i], "-app")) { strcpy(app_name, argv[++i]); } else if (!strcmp(argv[i], "-d")) { boinc_validator_debuglevel=atoi(argv[++i]); log_messages.set_debug_level(boinc_validator_debuglevel); } else if (!strcmp(argv[i], "-mod")) { wu_id_modulus = atoi(argv[++i]); wu_id_remainder = atoi(argv[++i]); } else if (!strcmp(argv[i], "-max_granted_credit")) { max_granted_credit = atof(argv[++i]); } else if (!strcmp(argv[i], "-max_claimed_credit")) { max_claimed_credit = atof(argv[++i]); } else if (!strcmp(argv[i], "-grant_claimed_credit")) { grant_claimed_credit = true; } else if (!strcmp(argv[i], "-update_credited_job")) { update_credited_job = true; } else if (!strcmp(argv[i], "-credit_from_wu")) { credit_from_wu = true; } else { fprintf(stderr, "Invalid option '%s'\nTry `%s --help` for more information\n", argv[i], argv[0]); log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "unrecognized arg: %s\n", argv[i]); exit(1); } } credit_from_wu = true; // always use the credit amount from the workunit template grant_claimed_credit = false; // -app is required if ( app_name[0] == 0 ) { fprintf (stderr, "\nERROR: use '-app' to specify the application to run the validator for.\n"); printf (usage, argv[0] ); exit(1); } retval = config.parse_file(".."); if (retval) { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "Can't parse ../config.xml: %s\n", boincerror(retval) ); exit(1); } log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, "Starting validator, debug level %d\n", log_messages.debug_level ); if (wu_id_modulus) { log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, "Modulus %d, remainder %d\n", wu_id_modulus, wu_id_remainder ); } install_stop_signal_handler(); main_loop();}const char *BOINC_RCSID_634dbda0b9 = "$Id: validator.C 14436 2007-12-21 21:09:40Z davea $";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -