. // remote job submission API //// Implementation stuff follows function req_to_xml($req, $op) { $x = "<$op> $req->authenticator $req->app_name $req->batch_name "; foreach ($req->jobs as $job) { $x .= " $job->rsc_fpops_est $job->command_line "; foreach ($job->input_files as $file) { $x .= " $file->source "; } $x .= " "; } $x .= " "; return $x; } function validate_request($req) { if (!is_object($req)) return "req is not an object"; if (!array_key_exists('project', $req)) return "missing req->project"; if (!array_key_exists('authenticator', $req)) return "missing req->authenticator"; if (!array_key_exists('app_name', $req)) return "missing req->app_name"; if (!array_key_exists('jobs', $req)) return "missing req->jobs"; if (!is_array($req->jobs)) return "req->jobs is not an array"; foreach ($req->jobs as $job) { // other checks } return null; } function do_http_op($project, $xml) { $ch = curl_init("$project/submit.php"); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, "request=$xml"); $reply = curl_exec($ch); if (!$reply) return array(null, "HTTP error"); $r = simplexml_load_string($reply); if (!$r) return array(null, "Can't parse reply XML:
".htmlentities($reply)."
"); return array($r, null); } function do_batch_op($req, $op) { $retval = validate_request($req); if ($retval) return array(null, $retval); $xml = req_to_xml($req, $op); return do_http_op($req->project, $xml); } //// Interface functions follow function boinc_estimate_batch($req) { list($reply, $errmsg) = do_batch_op($req, "estimate_batch"); if ($errmsg) return array(0, $errmsg); $name = $reply->getName(); if ($name == 'estimate') { return array((string)$reply->seconds, null); } else if ($name = 'error') { return array(null, (string)$reply->message); } else { return array(null, "Bad reply message"); } } function boinc_submit_batch($req) { list($reply, $errmsg) = do_batch_op($req, "submit_batch"); if ($errmsg) return array(0, $errmsg); $name = $reply->getName(); if ($name == 'batch_id') { return array((int)$reply, null); } else if ($name == 'error') { return array(null, (string)$reply->message); } else { return array(null, "Bad reply message"); } } function batch_xml_to_object($batch) { $b = null; $b->id = (int)($batch->id); $b->create_time = (double)($batch->create_time); $b->est_completion_time = (double)($batch->est_completion_time); $b->njobs = (int)($batch->njobs); $b->fraction_done = (double) $batch->fraction_done; $b->nerror_jobs = (int)($batch->nerror_jobs); $b->state = (int)($batch->state); $b->completion_time = (double)($batch->completion_time); $b->credit_estimate = (double)($batch->credit_estimate); $b->credit_canonical = (double)($batch->credit_canonical); $b->credit_total = (double)($batch->credit_total); $b->name = (string)($batch->name); $b->app_name = (string)($batch->app_name); return $b; } function boinc_query_batches($req) { $req_xml = " $req->authenticator "; list($reply, $errmsg) = do_http_op($req->project, $req_xml); if ($errmsg) return array(null, $errmsg); $batches = array(); foreach ($reply->batch as $batch) { $b = batch_xml_to_object($batch); $batches[] = $b; } return array($batches, null); } function boinc_query_batch($req) { $req_xml = " $req->authenticator $req->batch_id "; list($reply, $errmsg) = do_http_op($req->project, $req_xml); if ($errmsg) return array(null, $errmsg); $jobs = array(); foreach ($reply->job as $job) { $j = null; $j->id = (int)($job->id); $j->canonical_instance_id = (int)($job->canonical_instance_id); $jobs[] = $j; } $r = batch_xml_to_object($reply); $r->jobs = $jobs; return array($r, null); } function boinc_query_job($req) { $req_xml = " $req->authenticator $req->job_id "; list($reply, $errmsg) = do_http_op($req->project, $req_xml); if ($errmsg) return array(null, $errmsg); $instances = array(); foreach ($reply->instance as $instance) { $i = null; $i->name = (string)($instance->name); $i->id = (int)($instance->id); $i->state = (string)($instance->state); $i->outfiles = array(); foreach ($instance->outfile as $outfile) { $f = null; $f->size = (double)$outfile->size; $i->outfiles[] = $f; } $instances[] = $i; } $r = null; $r->instances = $instances; return array($r, null); } function boinc_abort_batch($req) { $req_xml = " $req->authenticator $req->batch_id "; list($reply, $errmsg) = do_http_op($req->project, $req_xml); if ($errmsg) return $errmsg; $name = $reply->getName(); if ($name == 'error') { return (string)($reply->message); } return null; } function boinc_get_output_file($req) { $auth_str = md5($req->authenticator.$req->instance_name); $name = $req->instance_name; $file_num = $req->file_num; return $req->project."/get_output.php?instance_name=$name&file_num=$file_num&auth_str=$auth_str"; } function boinc_get_output_files($req) { $auth_str = md5($req->authenticator.$req->batch_id); $batch_id = $req->batch_id; return $req->project."/get_output.php?batch_id=$batch_id&auth_str=$auth_str"; } function boinc_retire_batch($req) { $req_xml = " $req->authenticator $req->batch_id "; list($reply, $errmsg) = do_http_op($req->project, $req_xml); if ($errmsg) return $errmsg; $name = $reply->getName(); if ($name == 'error') { return (string)($reply->message); } return null; } function batch_state_string($state) { switch ($state) { case BATCH_STATE_INIT: return "New"; case BATCH_STATE_IN_PROGRESS: return "In progress"; case BATCH_STATE_COMPLETE: return "Completed"; case BATCH_STATE_ABORTED: return "Aborted"; case BATCH_STATE_RETIRED: return "Retired"; } return "Unknown state $state"; } //// example usage follows $req->project = "http://isaac.ssl.berkeley.edu/test/"; $req->authenticator = "x"; if (0) { $req->app_name = "uppercase"; $req->jobs = array(); $f->source = "http://isaac.ssl.berkeley.edu/index.php"; $job->input_files = array($f); for ($i=10; $i<20; $i++) { $job->rsc_fpops_est = $i*1e9; $job->command_line = "--t $i"; $req->jobs[] = $job; } if (0) { list($e, $errmsg) = boinc_estimate_batch($req); if ($errmsg) { echo "Error from server: $errmsg\n"; } else { echo "Batch completion estimate: $e seconds\n"; } } else { list($id, $errmsg) = boinc_submit_batch($req); if ($errmsg) { echo "Error from server: $errmsg\n"; } else { echo "Batch ID: $id\n"; } } } if (0) { list($batches, $errmsg) = boinc_query_batches($req); if ($errmsg) { echo "Error: $errmsg\n"; } else { print_r($batches); } } if (0) { $req->batch_id = 20; list($jobs, $errmsg) = boinc_query_batch($req); if ($errmsg) { echo "Error: $errmsg\n"; } else { print_r($jobs); } } ?>