2002-10-24 08:25:42 +00:00
|
|
|
// result_retry - create new results to make up for lost ones
|
|
|
|
//
|
|
|
|
// result_retry
|
|
|
|
// [ -dwu n ]
|
|
|
|
// [ -dresult n ]
|
|
|
|
// [ -nerror n ]
|
|
|
|
// [ -ndet n ]
|
|
|
|
// [ -nredundancy n ]
|
|
|
|
|
2002-11-05 18:36:09 +00:00
|
|
|
#include <vector>
|
|
|
|
#include <sys/time.h>
|
|
|
|
|
|
|
|
#include "db.h"
|
|
|
|
|
|
|
|
int max_errors = 999;
|
|
|
|
int max_done = 999;
|
|
|
|
int nredundancy = 999;
|
|
|
|
int startup_time;
|
|
|
|
|
|
|
|
// The scheme for generating unique output filenames is as follows.
|
|
|
|
// If the original filename is of the form x__y,
|
|
|
|
// then y is replaced with a string of the form time_seqno,
|
|
|
|
// where "time" is when this program started up.
|
|
|
|
// NOTE: if you ever need to start up multiple copies of this,
|
|
|
|
// you'll need to add a PID in there somewhere.
|
|
|
|
//
|
|
|
|
// If the original filename doesn't have __, add a string
|
|
|
|
// of the form __time_seqno
|
|
|
|
|
|
|
|
void make_unique_name(char* name) {
|
|
|
|
char buf[256], *p;
|
|
|
|
static int seqno;
|
|
|
|
|
|
|
|
sprintf(buf, "%d_%d", startup_time, seqno);
|
|
|
|
p = strstr(name, "__");
|
|
|
|
if (p) {
|
|
|
|
strcpy(p+2, buf);
|
|
|
|
} else {
|
|
|
|
strcat(name, buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// convert a result's XML document to generate new output filenames
|
|
|
|
// Look for <name>...</name> elements and convert the name;
|
|
|
|
// apply the same conversion to the <file_name> element later on.
|
|
|
|
//
|
|
|
|
int assign_new_names(char* in, char* out) {
|
|
|
|
char *p = in, *n1, *n2;
|
|
|
|
char name[256], buf[MAX_BLOB_SIZE];
|
|
|
|
int len;
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
n1 = strstr(p, "<name>");
|
|
|
|
if (!n1) break;
|
|
|
|
n1 += strlen("<name>");
|
|
|
|
n2 = strstr(p, "</name>");
|
|
|
|
if (!n2) {
|
|
|
|
fprintf(stderr, "malformed XML:\n%s", in);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
len = n2 - n1;
|
|
|
|
memcpy(name, n1, len);
|
|
|
|
name[len] = 0;
|
|
|
|
make_unique_name(name);
|
|
|
|
strcpy(buf, n2);
|
|
|
|
strcpy(n1, name);
|
|
|
|
strcat(n1, buf);
|
|
|
|
p = n1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-10-24 08:25:42 +00:00
|
|
|
void main_loop() {
|
|
|
|
WORKUNIT wu;
|
|
|
|
RESULT result;
|
2002-11-03 23:05:12 +00:00
|
|
|
int nerrors, ndone;
|
2002-11-05 18:36:09 +00:00
|
|
|
unsigned int i, n;
|
2002-10-24 08:25:42 +00:00
|
|
|
|
|
|
|
wu.retry_check_time = time(0);
|
2002-11-03 23:05:12 +00:00
|
|
|
|
|
|
|
// loop over WUs that are due to be checked
|
|
|
|
//
|
2002-11-05 18:36:09 +00:00
|
|
|
while (db_workunit_enum_retry_check_time(wu)) {
|
2002-10-24 08:25:42 +00:00
|
|
|
vector<RESULT> results;
|
2002-11-03 23:05:12 +00:00
|
|
|
|
|
|
|
// enumerate all the results for the WU
|
|
|
|
//
|
2002-10-24 08:25:42 +00:00
|
|
|
result.workunitid = wu.id;
|
2002-11-05 18:36:09 +00:00
|
|
|
while (db_result_enum_wuid(result)) {
|
2002-10-24 08:25:42 +00:00
|
|
|
results.push_back(result);
|
|
|
|
}
|
2002-11-03 23:05:12 +00:00
|
|
|
|
|
|
|
nerrors = 0;
|
|
|
|
ndone = 0;
|
|
|
|
for (i=0; i<results.size(); i++) {
|
2002-11-05 18:36:09 +00:00
|
|
|
result = results[i];
|
2002-11-03 23:05:12 +00:00
|
|
|
|
|
|
|
// if any result is unsent, give up on the WU
|
|
|
|
//
|
|
|
|
if (result.state == RESULT_STATE_UNSENT) {
|
|
|
|
fprintf(stderr, "WU %s has unsent result\n", wu.name);
|
|
|
|
wu.state = WU_STATE_SEND_FAIL;
|
|
|
|
db_workunit_update(wu);
|
|
|
|
goto next_wu;
|
|
|
|
}
|
|
|
|
if (result.state == RESULT_STATE_ERROR) {
|
|
|
|
nerrors++;
|
|
|
|
}
|
|
|
|
if (result.state == RESULT_STATE_DONE) {
|
|
|
|
ndone++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// it too many errors or too many different results, bail
|
|
|
|
//
|
|
|
|
if (nerrors > max_errors) {
|
|
|
|
fprintf(stderr, "WU %s has too many errors\n", wu.name);
|
|
|
|
wu.state = WU_STATE_TOO_MANY_ERRORS;
|
|
|
|
db_workunit_update(wu);
|
2002-11-05 18:36:09 +00:00
|
|
|
goto next_wu;
|
2002-11-03 23:05:12 +00:00
|
|
|
}
|
|
|
|
if (ndone > max_done) {
|
|
|
|
fprintf(stderr, "WU %s has too many answers\n", wu.name);
|
|
|
|
wu.state = WU_STATE_TOO_MANY_DONE;
|
|
|
|
db_workunit_update(wu);
|
2002-11-05 18:36:09 +00:00
|
|
|
goto next_wu;
|
2002-11-03 23:05:12 +00:00
|
|
|
}
|
|
|
|
|
2002-11-05 18:36:09 +00:00
|
|
|
// Generate new results if needed.
|
|
|
|
// Munge the XML of an existing result
|
|
|
|
// to create unique new output filenames.
|
2002-11-03 23:05:12 +00:00
|
|
|
//
|
|
|
|
n = nredundancy - ndone;
|
|
|
|
for (i=0; i<n; i++) {
|
|
|
|
create_result(
|
|
|
|
wu, result_template_file, suffix, key,
|
|
|
|
config.upload_url, config.download_url
|
|
|
|
);
|
|
|
|
}
|
|
|
|
next_wu:
|
2002-10-24 08:25:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char** argv) {
|
2002-11-05 18:36:09 +00:00
|
|
|
int i;
|
|
|
|
bool asynch = false;
|
|
|
|
|
|
|
|
startup_time = time(0);
|
|
|
|
for (i=1; i<argc; i++) {
|
|
|
|
if (!strcmp(argv[i], "-nerror")) {
|
|
|
|
max_errors = atoi(argv[++i]);
|
|
|
|
} else if (!strcmp(argv[i], "-ndet")) {
|
|
|
|
max_done = atoi(argv[++i]);
|
|
|
|
} else if (!strcmp(argv[i], "-asynch")) {
|
|
|
|
asynch = true;
|
|
|
|
} else if (!strcmp(argv[i], "-nredundancy")) {
|
|
|
|
nredundancy = atoi(argv[++i]);;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (asynch) {
|
|
|
|
if (fork()==0) {
|
|
|
|
while(1) {
|
|
|
|
main_loop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
while (1) {
|
|
|
|
main_loop();
|
|
|
|
}
|
|
|
|
}
|
2002-10-24 08:25:42 +00:00
|
|
|
}
|