// Send targeted jobs of a given type. // NOTE: there may be an atomicity problem in the following. // Ideally it should be in a transaction. // bool send_jobs(int assign_type) { DB_ASSIGNMENT asg; DB_RESULT result; DB_WORKUNIT wu; int retval; bool sent_something = false; char query[256]; switch (assign_type) { case ASSIGN_USER: sprintf(query, "where target_type=%d and target_id=%lu and multi=0", ASSIGN_USER, g_reply->user.id ); break; case ASSIGN_HOST: sprintf(query, "where target_type=%d and target_id=%lu and multi=0", ASSIGN_HOST, g_reply->host.id ); break; case ASSIGN_TEAM: sprintf(query, "where target_type=%d and target_id=%lu and multi=0", ASSIGN_TEAM, g_reply->team.id ); break; } while (!asg.enumerate(query)) { if (!work_needed(false)) { asg.end_enumerate(); break; } // if the WU doesn't exist, delete the assignment record. // retval = wu.lookup_id(asg.workunitid); if (retval) { asg.delete_from_db(); continue; } if (!need_targeted_instance(wu, g_reply->host.id)) { continue; } // OK, send the job // if (config.debug_send) { log_messages.printf(MSG_NORMAL, "sending targeted job: %s\n", wu.name ); } retval = send_assigned_job(asg); if (retval) { log_messages.printf(MSG_NORMAL, "failed to send targeted job: %s\n", boincerror(retval) ); continue; } sent_something = true; // update the WU's transition time to time out this job // retval = wu.lookup_id(asg.workunitid); if (retval) continue; int new_tt = time(0) + wu.delay_bound; if (new_tt < wu.transition_time) { char buf2[256]; sprintf(buf2, "transition_time=%d", new_tt); wu.update_field(buf2); } } return sent_something; }
// send non-multi assigned jobs // bool send_assigned_jobs() { DB_ASSIGNMENT asg; DB_RESULT result; DB_WORKUNIT wu; bool sent_something = false; int retval; // for now, only look for user assignments // char buf[256]; sprintf(buf, "where target_type=%d and target_id=%d and multi=0", ASSIGN_USER, g_reply->user.id ); while (!asg.enumerate(buf)) { if (!work_needed(false)) continue; // if the WU doesn't exist, delete the assignment record. // retval = wu.lookup_id(asg.workunitid); if (retval) { asg.delete_from_db(); continue; } // don't send if WU is validation pending or completed, // or has transition pending // if (wu.need_validate) continue; if (wu.canonical_resultid) continue; if (wu.transition_time < time(0)) continue; // don't send if we already sent one to this host // sprintf(buf, "where workunitid=%d and hostid=%d", asg.workunitid, g_request->host.id ); retval = result.lookup(buf); if (retval != ERR_DB_NOT_FOUND) continue; // don't send if there's already one in progress to this user // sprintf(buf, "where workunitid=%d and userid=%d and server_state=%d", asg.workunitid, g_reply->user.id, RESULT_SERVER_STATE_IN_PROGRESS ); retval = result.lookup(buf); if (retval != ERR_DB_NOT_FOUND) continue; // OK, send the job // retval = send_assigned_job(asg); if (retval) continue; sent_something = true; // update the WU's transition time to time out this job // retval = wu.lookup_id(asg.workunitid); if (retval) continue; int new_tt = time(0) + wu.delay_bound; if (new_tt < wu.transition_time) { char buf2[256]; sprintf(buf2, "transition_time=%d", new_tt); wu.update_field(buf2); } } return sent_something; }
// return true if did anything // bool do_pass() { int retval = 0; // The number of workunits/results purged in a single pass of do_pass(). // Since do_pass() may be invoked multiple times, // corresponding global variables store global totals. // int do_pass_purged_workunits = 0; int do_pass_purged_results = 0; int min_age_seconds = 0; // check to see if we got a stop signal. // Note that if we do catch a stop signal here, // we call an exit handler that closes [and optionally compresses] files // before returning to the OS. // check_stop_daemons(); bool did_something = false; DB_WORKUNIT wu; char buf[256]; if (min_age_days) { min_age_seconds = (int) min_age_days*86400; if (id_modulus) { sprintf(buf, "where file_delete_state=%d and mod_time<current_timestamp() - interval %d second and id %% %d = %d limit %d", FILE_DELETE_DONE, min_age_seconds, id_modulus, id_remainder, DB_QUERY_LIMIT ); } else { sprintf(buf, "where file_delete_state=%d and mod_time<current_timestamp() - interval %d second limit %d", FILE_DELETE_DONE, min_age_seconds, DB_QUERY_LIMIT ); } } else { if (id_modulus) { sprintf(buf, "where file_delete_state=%d and id %% %d = %d limit %d", FILE_DELETE_DONE, id_modulus, id_remainder, DB_QUERY_LIMIT ); } else { sprintf(buf, "where file_delete_state=%d limit %d", FILE_DELETE_DONE, DB_QUERY_LIMIT ); } } int n=0; while (1) { retval = wu.enumerate(buf); if (retval) { if (retval != ERR_DB_NOT_FOUND) { log_messages.printf(MSG_DEBUG, "DB connection lost, exiting\n" ); exit(0); } break; } if (strstr(wu.name, "nodelete")) continue; did_something = true; // if archives have not already been opened, then open them. // if (!no_archive && !wu_stream) { open_all_archives(); } retval = purge_and_archive_results(wu, n); do_pass_purged_results += n; if (!no_archive) { retval= archive_wu(wu); if (retval) { log_messages.printf(MSG_CRITICAL, "Failed to write to XML file workunit:%d\n", wu.id ); exit(5); } log_messages.printf(MSG_DEBUG, "Archived workunit [%d] to a file\n", wu.id ); } // purge workunit from DB // if (!dont_delete) { retval= wu.delete_from_db(); if (retval) { log_messages.printf(MSG_CRITICAL, "Can't delete workunit [%d] from database:%d\n", wu.id, retval ); exit(6); } if (config.enable_assignment) { DB_ASSIGNMENT asg; sprintf(buf, "where workunitid=%d", wu.id); retval = asg.lookup(buf); if (!retval) { asg.delete_from_db(); } } } log_messages.printf(MSG_DEBUG, "Purged workunit [%d] from database\n", wu.id ); if (config.enable_assignment) { DB_ASSIGNMENT asg; char buf2[256]; sprintf(buf2, "workunitid=%d", wu.id); asg.delete_from_db_multi(buf2); } purged_workunits++; do_pass_purged_workunits++; wu_stored_in_file++; if (!no_archive) { fflush(NULL); // if file has got max # of workunits, close and compress it. // This sets file pointers to NULL // if (max_wu_per_file && wu_stored_in_file>=max_wu_per_file) { close_all_archives(); wu_stored_in_file = 0; } } if (time_to_quit()) { break; } } if (do_pass_purged_workunits) { log_messages.printf(MSG_NORMAL, "Archived %d workunits and %d results\n", do_pass_purged_workunits, do_pass_purged_results ); } if (did_something && wu_stored_in_file>0) { log_messages.printf(MSG_DEBUG, "Currently open archive files contain %d workunits\n", wu_stored_in_file ); } if (do_pass_purged_workunits > DB_QUERY_LIMIT/2) { return true; } else { return false; } }