mirror of https://github.com/BOINC/boinc.git
Make sure the work unit is marked as done when the DC_Result is destroyed
Remember the database ID of WUs to prevent unneccessary database lookups Quote the client's command line arguments when creating the command line git-svn-id: svn+ssh://cvs.lpds.sztaki.hu/var/lib/svn/szdg/dcapi/trunk@429 a7169a2c-3604-0410-bc95-c702d8d87f7a
This commit is contained in:
parent
9933363483
commit
199abba0e2
|
@ -138,8 +138,9 @@ char *DC_resolveFileName(DC_FileType type, const char *logicalFileName)
|
|||
}
|
||||
|
||||
int DC_sendResult(const char *logicalFileName, const char *path,
|
||||
DC_FileMode fileMode)
|
||||
DC_FileMode mode)
|
||||
{
|
||||
/* XXX */
|
||||
return DC_ERR_NOTIMPL;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,3 +25,52 @@ int _DC_initDB(void)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lookup_db_id(DC_Workunit *wu)
|
||||
{
|
||||
char *query, *name;
|
||||
DB_WORKUNIT dbwu;
|
||||
int ret;
|
||||
|
||||
if (wu->db_id)
|
||||
return 0;
|
||||
|
||||
name = _DC_getWUName(wu);
|
||||
query = g_strdup_printf("WHERE name = '%s'", name);
|
||||
g_free(name);
|
||||
ret = dbwu.lookup(query);
|
||||
g_free(query);
|
||||
|
||||
if (ret)
|
||||
return DC_ERR_DATABASE;
|
||||
wu->db_id = dbwu.get_id();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _DC_resultCompleted(DC_Result *result)
|
||||
{
|
||||
char *query;
|
||||
int ret;
|
||||
|
||||
if (!result->wu->db_id)
|
||||
{
|
||||
ret = lookup_db_id(result->wu);
|
||||
if (ret)
|
||||
{
|
||||
char *name = _DC_getWUName(result->wu);
|
||||
|
||||
DC_log(LOG_ERR, "Failed to look up the ID of WU %s",
|
||||
name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* We could use DB_WORKUNIT but that would require doing a SELECT
|
||||
* before the UPDATE, which is unneccessary */
|
||||
query = g_strdup_printf("UPDATE workunit "
|
||||
"SET assimilate_state = %d, transition_time = %d "
|
||||
"WHERE id = %d", ASSIMILATE_DONE, (int)time(NULL),
|
||||
result->wu->db_id);
|
||||
boinc_db.do_query(query);
|
||||
g_free(query);
|
||||
}
|
||||
|
|
|
@ -48,10 +48,14 @@ struct _DC_Workunit
|
|||
char *tag;
|
||||
int subresults;
|
||||
|
||||
/* State of the WU */
|
||||
/* The WU's UUID */
|
||||
uuid_t uuid;
|
||||
/* State of the WU */
|
||||
DC_WUState state;
|
||||
/* The WU's working directory */
|
||||
char *workdir;
|
||||
/* The WU's ID in the Boinc database */
|
||||
int db_id;
|
||||
|
||||
/* Input file definitions. Elements are of type DC_LogicalFile */
|
||||
GList *input_files;
|
||||
|
@ -128,18 +132,24 @@ DC_PhysicalFile *_DC_createPhysicalFile(const char *label,
|
|||
void _DC_destroyPhysicalFile(DC_PhysicalFile *file) G_GNUC_INTERNAL;
|
||||
|
||||
/* Creates a new DC_Result */
|
||||
DC_Result *_DC_createResult(const char *wu_name, const char *xml_doc_in)
|
||||
G_GNUC_INTERNAL;
|
||||
DC_Result *_DC_createResult(const char *wu_name, int db_id,
|
||||
const char *xml_doc_in) G_GNUC_INTERNAL;
|
||||
|
||||
/* Destroys a DC_Result */
|
||||
void _DC_destroyResult(DC_Result *result) G_GNUC_INTERNAL;
|
||||
|
||||
/* Get the name of the WU used in the database */
|
||||
char *_DC_getWUName(DC_Workunit *wu) G_GNUC_INTERNAL;
|
||||
|
||||
/* Looks up a WU by name */
|
||||
DC_Workunit *_DC_getWUByName(const char *name) G_GNUC_INTERNAL;
|
||||
|
||||
/* Parses <file_ref> definitions in an XML document */
|
||||
GList *_DC_parseFileRefs(const char *xml_doc, int *num_files) G_GNUC_INTERNAL;
|
||||
|
||||
/* Marks a work unit as completed in the database */
|
||||
void _DC_resultCompleted(DC_Result *result) G_GNUC_INTERNAL;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -48,16 +48,11 @@ int DC_processEvents(int timeout)
|
|||
}
|
||||
|
||||
/* Call the callback function */
|
||||
result = _DC_createResult(wu.name, canonical_result.xml_doc_in);
|
||||
result = _DC_createResult(wu.name, wu.id, canonical_result.xml_doc_in);
|
||||
if (!result)
|
||||
continue;
|
||||
_dc_resultcb(result->wu, result);
|
||||
_DC_destroyResult(result);
|
||||
|
||||
/* Mark the work unit as completed */
|
||||
wu.assimilate_state = ASSIMILATE_DONE;
|
||||
wu.transition_time = time(0);
|
||||
wu.update();
|
||||
}
|
||||
|
||||
g_free(query);
|
||||
|
@ -102,12 +97,13 @@ static DC_Event *look_for_results(const char *wuFilter, const char *wuName,
|
|||
|
||||
event = g_new(DC_Event, 1);
|
||||
event->type = DC_EVENT_RESULT;
|
||||
event->result = _DC_createResult(wu.name, result.xml_doc_in);
|
||||
event->result = _DC_createResult(wu.name, wu.id, result.xml_doc_in);
|
||||
if (!event->result)
|
||||
{
|
||||
g_free(event);
|
||||
return NULL;
|
||||
}
|
||||
event->wu = event->result->wu;
|
||||
|
||||
return event;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
* Functions
|
||||
*/
|
||||
|
||||
DC_Result *_DC_createResult(const char *wu_name, const char *xml_doc_in)
|
||||
DC_Result *_DC_createResult(const char *wu_name, int db_id,
|
||||
const char *xml_doc_in)
|
||||
{
|
||||
DC_Result *result;
|
||||
|
||||
|
@ -25,6 +26,9 @@ DC_Result *_DC_createResult(const char *wu_name, const char *xml_doc_in)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (!result->wu->db_id)
|
||||
result->wu->db_id = db_id;
|
||||
|
||||
result->wu->state = DC_WU_FINISHED;
|
||||
|
||||
result->output_files = _DC_parseFileRefs(xml_doc_in,
|
||||
|
@ -39,6 +43,9 @@ DC_Result *_DC_createResult(const char *wu_name, const char *xml_doc_in)
|
|||
|
||||
void _DC_destroyResult(DC_Result *result)
|
||||
{
|
||||
/* Mark the work unit as completed in the database */
|
||||
_DC_resultCompleted(result);
|
||||
|
||||
while (result->output_files)
|
||||
{
|
||||
_DC_destroyPhysicalFile(result->output_files->data);
|
||||
|
|
|
@ -664,8 +664,8 @@ static int install_input_files(DC_Workunit *wu)
|
|||
|
||||
static char *generate_wu_template(DC_Workunit *wu)
|
||||
{
|
||||
GString *tmpl, *cmd;
|
||||
int i, num_inputs;
|
||||
GString *tmpl;
|
||||
GList *l;
|
||||
char *p;
|
||||
|
||||
|
@ -705,11 +705,21 @@ static char *generate_wu_template(DC_Workunit *wu)
|
|||
g_string_append(tmpl, "\t</file_ref>\n");
|
||||
}
|
||||
|
||||
/* XXX Should qoute the individual arguments */
|
||||
p = g_strjoinv(" ", wu->argv);
|
||||
/* Concatenate the shell-quoted argv elements into a single string */
|
||||
cmd = g_string_new("");
|
||||
for (i = 0; i < wu->argc; i++)
|
||||
{
|
||||
char *quoted;
|
||||
|
||||
if (i)
|
||||
g_string_append_c(cmd, ' ');
|
||||
quoted = g_shell_quote(wu->argv[i]);
|
||||
g_string_append(cmd, quoted);
|
||||
g_free(quoted);
|
||||
}
|
||||
g_string_append_printf(tmpl,
|
||||
"\t<command_line>%s</command_line>\n", p);
|
||||
g_free(p);
|
||||
"\t<command_line>%s</command_line>\n", cmd->str);
|
||||
g_string_free(cmd, TRUE);
|
||||
|
||||
g_string_append(tmpl,
|
||||
"\t<rsc_fpops_est>1e13</rsc_fpops_est>\n"); /* XXX Check */
|
||||
|
@ -828,37 +838,46 @@ static int lookup_appid(DC_Workunit *wu)
|
|||
return app.get_id();
|
||||
}
|
||||
|
||||
char *_DC_getWUName(DC_Workunit *wu)
|
||||
{
|
||||
char uuid_str[37];
|
||||
|
||||
uuid_unparse_lower(wu->uuid, uuid_str);
|
||||
if (wu->tag)
|
||||
return g_strdup_printf("%s_%s_%s", project_uuid_str, uuid_str,
|
||||
wu->tag);
|
||||
else
|
||||
return g_strdup_printf("%s_%s", project_uuid_str, uuid_str);
|
||||
}
|
||||
|
||||
int DC_submitWU(DC_Workunit *wu)
|
||||
{
|
||||
char *wu_template, *result_template_file, **infiles, *result_path,
|
||||
uuid_str[37];
|
||||
char *wu_template, *result_template_file, **infiles, *result_path, *name;
|
||||
int i, ret, ninputs;
|
||||
DB_WORKUNIT bwu;
|
||||
DB_WORKUNIT dbwu;
|
||||
GList *l;
|
||||
|
||||
ret = install_input_files(wu);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
uuid_unparse_lower(wu->uuid, uuid_str);
|
||||
if (wu->tag)
|
||||
snprintf(bwu.name, sizeof(bwu.name), "%s_%s_%s",
|
||||
project_uuid_str, uuid_str, wu->tag);
|
||||
else
|
||||
snprintf(bwu.name, sizeof(bwu.name), "%s_%s",
|
||||
project_uuid_str, uuid_str);
|
||||
dbwu.clear();
|
||||
|
||||
bwu.appid = lookup_appid(wu);
|
||||
if (bwu.appid == -1)
|
||||
name = _DC_getWUName(wu);
|
||||
snprintf(dbwu.name, sizeof(dbwu.name), "%s", name);
|
||||
g_free(name);
|
||||
|
||||
dbwu.appid = lookup_appid(wu);
|
||||
if (dbwu.appid == -1)
|
||||
return DC_ERR_DATABASE;
|
||||
|
||||
/* XXX Make these compatible with the template */
|
||||
bwu.batch = 1;
|
||||
bwu.rsc_fpops_est = 200000 ;
|
||||
bwu.rsc_fpops_bound = 2000000000 ;
|
||||
bwu.rsc_memory_bound = 2000000;
|
||||
bwu.rsc_disk_bound = 2000000;
|
||||
bwu.delay_bound = 720000;
|
||||
dbwu.batch = 1;
|
||||
dbwu.rsc_fpops_est = 200000;
|
||||
dbwu.rsc_fpops_bound = 2000000000;
|
||||
dbwu.rsc_memory_bound = 2000000;
|
||||
dbwu.rsc_disk_bound = 2000000;
|
||||
dbwu.delay_bound = 720000;
|
||||
|
||||
wu_template = generate_wu_template(wu);
|
||||
result_template_file = generate_result_template(wu);
|
||||
|
@ -882,7 +901,7 @@ int DC_submitWU(DC_Workunit *wu)
|
|||
/* Terminator so we can use g_strfreev() later */
|
||||
infiles[i] = NULL;
|
||||
|
||||
ret = create_work(bwu, wu_template, result_template_file, result_path,
|
||||
ret = create_work(dbwu, wu_template, result_template_file, result_path,
|
||||
const_cast<const char **>(infiles), wu->num_inputs,
|
||||
dc_boinc_config);
|
||||
g_free(result_path);
|
||||
|
@ -1076,6 +1095,15 @@ DC_Workunit *_DC_getWUByName(const char *name)
|
|||
return load_from_disk(uuid);
|
||||
}
|
||||
|
||||
static void count_ready(void *key, void *value, void *ptr)
|
||||
{
|
||||
DC_Workunit *wu = (DC_Workunit *)value;
|
||||
int *count = (int *)ptr;
|
||||
|
||||
if (wu->state == DC_WU_READY)
|
||||
++(*count);
|
||||
}
|
||||
|
||||
int DC_getWUNumber(DC_WUState state)
|
||||
{
|
||||
DB_BASE db("", &boinc_db);
|
||||
|
@ -1085,8 +1113,11 @@ int DC_getWUNumber(DC_WUState state)
|
|||
switch (state)
|
||||
{
|
||||
case DC_WU_READY:
|
||||
/* XXX Should walk the wu_table */
|
||||
return -1;
|
||||
val = 0;
|
||||
if (wu_table)
|
||||
g_hash_table_foreach(wu_table, count_ready,
|
||||
&val);
|
||||
return val;
|
||||
case DC_WU_RUNNING:
|
||||
query = g_strdup_printf("SELECT COUNT(*) "
|
||||
"FROM workunit wu, result res WHERE "
|
||||
|
@ -1115,5 +1146,4 @@ int DC_getWUNumber(DC_WUState state)
|
|||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue