boinc/sched/sample_work_generator.C

179 lines
5.1 KiB
C

// Berkeley Open Infrastructure for Network Computing
// http://boinc.berkeley.edu
// Copyright (C) 2007 University of California
//
// This 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 2.1 of the License, or (at your option) any later version.
//
// This software 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.
//
// To view the GNU Lesser General Public License visit
// http://www.gnu.org/copyleft/lesser.html
// or write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// sample_work_generator.C: an example BOINC work generator.
// This work generator has the following properties
// (you may need to change some or all of these):
//
// - Runs as a daemon, and creates an unbounded supply of work.
// It attempts to maintain a "cushion" of 100 unsent job instances.
// (your app may not work this way; e.g. you might create work in batches)
// - Creates work for the application "uppercase".
// - Creates a new input file for each job;
// the file (and the workunit names) contain a timestamp
// and sequence number, so that they're unique.
#include "boinc_db.h"
#include "error_numbers.h"
#include "backend_lib.h"
#include "parse.h"
#include "sched_config.h"
#include "sched_util.h"
#include "sched_msgs.h"
#define CUSHION 100
// maintain at least this many unsent results
#define REPLICATION_FACTOR 2
// globals
//
char* wu_template;
DB_APP app;
int start_time;
int seqno;
SCHED_CONFIG config;
// create one new job
//
int make_job() {
DB_WORKUNIT wu;
char name[256], path[256], buf[256];
const char* infiles[1];
int retval;
// make a unique name (for the job and its input file)
//
sprintf(name, "uc_%d_%d", start_time, seqno++);
// Create the input file.
// Put it at the right place in the download dir hierarchy
//
retval = config.download_path(name, path);
if (retval) return retval;
FILE* f = fopen(path, "w");
if (!f) return ERR_FOPEN;
fprintf(f, "This is the input file for job %s", name);
fclose(f);
// Fill in the job parameters
//
wu.clear();
wu.appid = app.id;
strcpy(wu.name, name);
wu.rsc_fpops_est = 1e12;
wu.rsc_fpops_bound = 1e14;
wu.rsc_memory_bound = 1e8;
wu.rsc_disk_bound = 1e8;
wu.delay_bound = 86400;
wu.min_quorum = REPLICATION_FACTOR;
wu.target_nresults = REPLICATION_FACTOR;
wu.max_error_results = REPLICATION_FACTOR*4;
wu.max_total_results = REPLICATION_FACTOR*8;
wu.max_success_results = REPLICATION_FACTOR*4;
infiles[0] = name;
// Register the job with BOINC
//
return create_work(
wu,
wu_template,
"templates/uc_result",
"../templates/uc_result",
infiles,
1,
config
);
}
void main_loop() {
int retval;
while (1) {
check_stop_daemons();
int n;
retval = count_unsent_results(n);
if (n > CUSHION) {
sleep(60);
} else {
int njobs = (CUSHION-n)/REPLICATION_FACTOR;
log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG,
"Making %d jobs\n", njobs
);
for (int i=0; i<njobs; i++) {
retval = make_job();
if (retval) {
log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,
"can't make job: %d\n", retval
);
exit(retval);
}
}
// Now sleep for a few seconds to let the transitioner
// create instances for the jobs we just created.
// Otherwise we could end up creating an excess of jobs.
sleep(5);
}
}
}
int main(int argc, char** argv) {
int i, retval;
for (i=1; i<argc; i++) {
if (!strcmp(argv[i], "-d")) {
log_messages.set_debug_level(atoi(argv[++i]));
} else {
log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,
"bad cmdline arg: %s", argv[i]
);
}
}
if (config.parse_file("..")) {
log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,
"can't read config file\n"
);
exit(1);
}
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, "can't open db\n");
exit(1);
}
if (app.lookup("where name='uppercase'")) {
log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "can't find app\n");
exit(1);
}
if (read_file_malloc("../templates/uc_wu", wu_template)) {
log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "can't read WU template\n");
exit(1);
}
start_time = time(0);
seqno = 0;
log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, "Starting\n");
main_loop();
}