示例#1
0
文件: job.cpp 项目: ReCodEx/worker
job::job(std::shared_ptr<job_metadata> job_meta,
	std::shared_ptr<worker_config> worker_conf,
	fs::path working_directory,
	fs::path source_path,
	fs::path result_path,
	std::shared_ptr<task_factory_interface> factory,
	std::shared_ptr<progress_callback_interface> progr_callback)
	: job_meta_(job_meta), worker_config_(worker_conf), working_directory_(working_directory),
	  source_path_(source_path), result_path_(result_path), factory_(factory), progress_callback_(progr_callback)
{
	// check construction parameters if they are in right format
	if (job_meta_ == nullptr) {
		throw job_exception("Job configuration cannot be null");
	} else if (worker_config_ == nullptr) {
		throw job_exception("Worker configuration cannot be null");
	} else if (factory_ == nullptr) {
		throw job_exception("Task factory pointer cannot be null");
	}

	// if progress callback is null, we have to use default one
	init_progress_callback();

	// check injected directories
	check_job_dirs();

	// prepare variables which will be used in job config
	prepare_job_vars();

	// construct system logger for this job
	init_logger();

	// build job from given job configuration
	build_job();
}
void job_receiver::setFilenamePattern(const std::string& filenamepattern) {
  if (jobfilename!=NULL) delete jobfilename;
  jobfilenamepattern=filenamepattern;
  jobfilenamesize=filenamepattern.size()+20;
  jobfilename=new char[jobfilenamesize];
  if (jobfilename==NULL) throw job_exception("could not allocate memory for filename");
}
示例#3
0
wait_job::wait_job(const size_t n, const XERCES_CPP_NAMESPACE_QUALIFIER DOMNamedNodeMap* attrs): control(n) {
    XMLCh* attr_name=XERCES_CPP_NAMESPACE_QUALIFIER XMLString::transcode("time");
    XERCES_CPP_NAMESPACE_QUALIFIER DOMNode* length_attr=attrs->getNamedItem(attr_name);
    XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&attr_name);
    if (length_attr==NULL) {
        attr_name=XERCES_CPP_NAMESPACE_QUALIFIER XMLString::transcode("length");
        length_attr=attrs->getNamedItem((XMLCh*)"time");
        XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&attr_name);
        if (length_attr==NULL)
            throw job_exception("length or time attribute required");
    }
    char* length_data=XERCES_CPP_NAMESPACE_QUALIFIER XMLString::transcode(length_attr->getNodeValue());
    char* parse_end=NULL;
    sec=strtod(length_data,&parse_end);
    int length_check=strlen(length_data)-(parse_end-length_data);
    XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&length_data);
    if (length_check!=0 || sec<=0)
        throw job_exception("wait: length attribute requires number>0");
}
示例#4
0
single_pulse_experiment::single_pulse_experiment(size_t n,const XERCES_CPP_NAMESPACE_QUALIFIER DOMNamedNodeMap* attrs): experiment(n) {
    t_before=0;
    frequency=1e4;
    sample_frequency=5e6;
    samples=1<<12;
    dac_value=3;

    // find pulse length
    XERCES_CPP_NAMESPACE_QUALIFIER  DOMNode* length_attr=attrs->getNamedItem((XMLCh*)"length");
    if (length_attr==NULL) throw job_exception("length attribute required");
    char* length_data=XERCES_CPP_NAMESPACE_QUALIFIER XMLString::transcode(length_attr->getNodeValue());
    pulse_length=strtod(length_data,NULL);
}
示例#5
0
文件: job.cpp 项目: ReCodEx/worker
std::string job::parse_job_var(const std::string &src)
{
	std::string res = src;

	size_t start = 0;
	while ((start = res.find("${", start)) != std::string::npos) {
		size_t end = res.find("}", start + 1);
		size_t len = end - start - 2;
		if (end == std::string::npos) {
			throw job_exception("Not closed variable name: " + res.substr(start));
		}

		if (job_variables_.find(res.substr(start + 2, len)) != job_variables_.end()) {
			// we found variable and can replace it in string
			res.replace(start, end - start + 1, job_variables_.at(res.substr(start + 2, len)));
		}

		// start++; // just to be sure we're not in cycle
	}

	return res;
}
job_receiver::job_receiver(std::string the_jobfilenamepattern) {
  try {
    XERCES_CPP_NAMESPACE_QUALIFIER XMLPlatformUtils::Initialize();
  }
  catch (const XERCES_CPP_NAMESPACE_QUALIFIER XMLException& toCatch) {
    char* ini_error=XERCES_CPP_NAMESPACE_QUALIFIER XMLString::transcode(toCatch.getMessage());
    job_exception new_exception(std::string("xerces initialisation error: ")+ini_error);
    XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&ini_error);
    throw new_exception;
  }

  jobfilename=NULL;
  setFilenamePattern(the_jobfilenamepattern);
  parser=new XERCES_CPP_NAMESPACE_QUALIFIER XercesDOMParser();
  if (parser==NULL) {
    delete jobfilename;
    throw job_exception("could not allocate parser");
  }
  parser->setValidationScheme(XERCES_CPP_NAMESPACE_QUALIFIER XercesDOMParser::Val_Always);
  parser->setDoNamespaces(true);
  errHandler = (XERCES_CPP_NAMESPACE_QUALIFIER ErrorHandler*) new XERCES_CPP_NAMESPACE_QUALIFIER HandlerBase();
  parser->setErrorHandler(errHandler);
}
示例#7
0
文件: job.cpp 项目: ReCodEx/worker
void job::connect_tasks(
	std::shared_ptr<task_base> root, std::map<std::string, std::shared_ptr<task_base>> &unconn_tasks)
{
	for (auto &elem : unconn_tasks) {
		const std::vector<std::string> &depend = elem.second->get_dependencies();

		// connect all suitable task underneath root
		if (depend.size() == 0) {
			root->add_children(elem.second);
			elem.second->add_parent(root);
		}

		for (size_t i = 0; i < depend.size(); ++i) {
			try {
				auto ptr = unconn_tasks.at(depend.at(i));
				ptr->add_children(elem.second);
				elem.second->add_parent(ptr);
			} catch (std::out_of_range) {
				throw job_exception("Non existing task-id (" + depend.at(i) + ") in dependency list");
			}
		}
	}
}
示例#8
0
文件: job.cpp 项目: ReCodEx/worker
void job::check_job_dirs()
{
	if (!fs::exists(working_directory_)) {
		throw job_exception("Working directory not exists");
	} else if (!fs::is_directory(working_directory_)) {
		throw job_exception("Working directory is not directory");
	}

	if (!fs::exists(source_path_)) {
		throw job_exception("Source code directory not exists");
	} else if (!fs::is_directory(source_path_)) {
		throw job_exception("Source code directory is not directory");
	} else if (fs::is_empty(source_path_)) {
		throw job_exception("Source code directory is empty");
	}

	// check result files directory
	if (!fs::exists(result_path_)) {
		throw job_exception("Result files directory not exists");
	} else if (!fs::is_directory(result_path_)) {
		throw job_exception("Result files directory is not directory");
	}
}
job* job_receiver::receive(const std::string& filename) {

  try {
    parser->parse(filename.c_str());
  }
  catch(const XERCES_CPP_NAMESPACE_QUALIFIER XMLException& toCatch) {
    char* message = XERCES_CPP_NAMESPACE_QUALIFIER XMLString::transcode(toCatch.getMessage());
    job_exception je(std::string("XML error: ")+message);
    XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&message);
    throw je;
  }
  catch(const XERCES_CPP_NAMESPACE_QUALIFIER DOMException& toCatch) {
    char* message = XERCES_CPP_NAMESPACE_QUALIFIER XMLString::transcode(toCatch.msg);
    job_exception je(std::string("XML DOM error: ")+message); 
    XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&message);
    throw je;
  }
  catch(const XERCES_CPP_NAMESPACE_QUALIFIER SAXParseException& toCatch) {
    // more verbose for parser errors
    char* message = XERCES_CPP_NAMESPACE_QUALIFIER XMLString::transcode(toCatch.getMessage());
    job_exception je(std::string("XML SAX Parser error: ")+message);
    char location[100];
    snprintf(location,sizeof(location),", line %ld column %ld",toCatch.getLineNumber(),toCatch.getColumnNumber());
    je.append(location);
    XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&message);
    throw je;
  }
  catch(const XERCES_CPP_NAMESPACE_QUALIFIER SAXException& toCatch) {
    char* message = XERCES_CPP_NAMESPACE_QUALIFIER XMLString::transcode(toCatch.getMessage());
    job_exception je(std::string("XML SAX error: ")+message); 
    XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&message);
    throw je;
  }

  // extract root element, root attributes and root name
  XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* doc=parser->getDocument();
  if (doc==NULL) throw job_exception("xml job document not found");
  XERCES_CPP_NAMESPACE_QUALIFIER DOMElement* rootelement=doc->getDocumentElement();
  if (rootelement==NULL) throw job_exception("xml job root document not found");
  char* docname=XERCES_CPP_NAMESPACE_QUALIFIER XMLString::transcode(rootelement->getNodeName());
  XERCES_CPP_NAMESPACE_QUALIFIER DOMNamedNodeMap* rootattrs=rootelement->getAttributes();

  // check the job number
  XMLCh* docnoname=XERCES_CPP_NAMESPACE_QUALIFIER XMLString::transcode("no");
  XERCES_CPP_NAMESPACE_QUALIFIER DOMNode* jobno_attr=rootattrs->getNamedItem(docnoname);
  XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&docnoname);
  if (jobno_attr==NULL) {
    docnoname=XERCES_CPP_NAMESPACE_QUALIFIER XMLString::transcode("no");
    jobno_attr=rootattrs->getNamedItem(docnoname);
    XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&docnoname);
  }
  size_t no=0;
  if (jobno_attr==NULL) fprintf(stderr,"Warning: job %" SIZETPRINTFLETTER ": root element has no job number\n",no);
  else {
    char* docno=XERCES_CPP_NAMESPACE_QUALIFIER XMLString::transcode(jobno_attr->getNodeValue());
    no=strtoul(docno,NULL,0);
    XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&docno);
  }

  job* this_job=NULL;
  // determine the job type by name
  if (strcasecmp(docname,"quit")==0) {
    this_job=new quit_job(no);
  }
  else if (strcasecmp(docname,"nop")==0) {
    this_job=new do_nothing_job(no);
  }
  else if (strcasecmp(docname,"pause")==0) {
    this_job=new pause_job(no);
  } /* pause */
  else if (strcasecmp(docname,"restart")==0) {
    this_job=new restart_job(no);
  } /* restart */
  else if (strcasecmp(docname,"wait")==0) {
    this_job=new wait_job(no,rootattrs);
  } /* wait */
  else if (strcasecmp(docname,"experiment")==0) {
    try {
      this_job=new experiment(no, rootelement);
    }
    catch (const XERCES_CPP_NAMESPACE_QUALIFIER DOMException& de) {
      char* domerrmsg=XERCES_CPP_NAMESPACE_QUALIFIER XMLString::transcode(de.msg);
      char domerrno[5];
      snprintf(domerrno,5,"%d",de.code);
      job_exception je("sorry, something happend while parsing experiment job: ");
      je.append(domerrmsg);
      je.append(", code ");
      je.append(domerrno);
      XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&domerrmsg);
      // cleanup missing
      throw je;
    }
  }
  else if (strcasecmp(docname,"configuration")==0) {
    try {
      this_job=new configuration(no, rootelement);
    }
    catch (const XERCES_CPP_NAMESPACE_QUALIFIER DOMException& de) {
      char* domerrmsg=XERCES_CPP_NAMESPACE_QUALIFIER XMLString::transcode(de.msg);
      char domerrno[5];
      snprintf(domerrno,5,"%d",de.code);
      job_exception je("sorry, something happend while parsing configuration job: ");
      je.append(domerrmsg);
      je.append(", code ");
      je.append(domerrno);
      XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&domerrmsg);
      // cleanup missing
      throw je;
    }
  }

  XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&docname);
  parser->reset();
  parser->resetDocument();
  parser->resetDocumentPool();

  return this_job;
}
示例#10
0
state_atom* experiment::state_factory(const XERCES_CPP_NAMESPACE_QUALIFIER DOMElement* element) {
    if (element==NULL) return NULL;

    char* my_name=XERCES_CPP_NAMESPACE_QUALIFIER XMLString::transcode(element->getNodeName());

    if(strcasecmp(my_name,"state")==0) {
        XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&my_name);
        // read parameters
        char* length_string=get_parameter(element,"length","time","t","l",NULL);
        if (length_string==NULL) throw job_exception("state requires length");
        char* length_string_end;
        double length=strtod(length_string,&length_string_end);
        int result=strlen(length_string)-(length_string_end-length_string);
        // here, we could search for us, s or ms, d or min
        XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&length_string);
        // but now we do not accept anything
        if (result!=0) throw job_exception("state requires length as floating point value");
        if (length<0) throw job_exception("state's length must be non-negative");
        state* new_state=new state(length);
        new_state->parent=NULL;

        // read states defintions
        XERCES_CPP_NAMESPACE_QUALIFIER DOMNode* one_child=element->getFirstChild();
        while (one_child!=NULL) {
            if (one_child->getNodeType()==XERCES_CPP_NAMESPACE_QUALIFIER DOMNode::ELEMENT_NODE) {
                state_atom* new_one=state_factory(dynamic_cast<XERCES_CPP_NAMESPACE_QUALIFIER DOMElement*>(one_child));
                if (new_one!=NULL) new_state->push_back(new_one);
            }
            one_child=one_child->getNextSibling();
        }
        return new_state;
    }
    else if(strcasecmp(my_name,"sequent")==0) {
        XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&my_name);
        // read parameters
        size_t repeat=1;
        // read parameters
        char* repeat_string=get_parameter(element,"repeat","n",NULL);
        if (repeat_string!=NULL) {
            char* repeat_string_end;
            double repeat_d=strtod(repeat_string,&repeat_string_end);
            int result=strlen(repeat_string)-(repeat_string_end-repeat_string);
            XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&repeat_string);
            // but now we do not accept anything
            if (result!=0 || repeat_d<0) throw job_exception("sequent requires loop count as a nonnegative integer value");
            repeat=(size_t)floor(repeat_d);
            if (1.0*repeat-repeat_d!=0) fprintf(stderr,"rounding non integer towards lower integer");
        }
        state_sequent* new_sequent=new state_sequent(repeat);
        new_sequent->parent=NULL;

        // read substates and subsequences
        XERCES_CPP_NAMESPACE_QUALIFIER DOMNode* one_child=element->getFirstChild();
        while (one_child!=NULL) {
            if (one_child->getNodeType()==XERCES_CPP_NAMESPACE_QUALIFIER DOMNode::ELEMENT_NODE) {
                state_atom* new_one=state_factory(dynamic_cast<XERCES_CPP_NAMESPACE_QUALIFIER DOMElement*>(one_child));
                if (new_one!=NULL) {
                    state* new_state=dynamic_cast<state*>(new_one);
                    if (new_state!=NULL) {
                        new_state->parent=new_sequent;
                        new_sequent->push_back(new_one);
                    }
                    else {
                        fprintf(stderr,"experiment: found nonstate in sequent element\n");
                        delete new_one;
                    }
                }
            }
            one_child=one_child->getNextSibling();
        }
        return new_sequent;
    }
    else if(strcasecmp(my_name,"ttlout")==0) {
        XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&my_name);
        // read parameters
        ttlout* ttls=new ttlout();
        char* id=get_parameter(element,"id","i",NULL);
        if (id!=NULL) {
            ttls->id=strtol(id,NULL,0);
            XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&id);
        }
        char* value=get_parameter(element,"value",NULL);
        if (value!=NULL) {
            ttls->ttls=strtoul(value,NULL,0);
            // todo: another error message...
            XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&value);
        }
        char* channel=get_parameter(element,"channel",NULL);
        if (channel!=NULL) {
            char* state_value=get_parameter(element,"state",NULL);
            if (state_value!=NULL) {
                size_t number=strtoul(channel,NULL,0);
                char state_char=(state_value)[0];
                fprintf(stderr, "been here\n");
                XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&state_value);
                if (state_char=='h' || state_char=='1')
                    ttls->ttls.set(number,1);
                else
                    ttls->ttls.set(number,0);
            }
            else {
                fprintf(stderr,"found invalid ttl state: ignoring\n");
                delete ttls;
                ttls=NULL;
            }
            XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&channel);
        }
        return (state_atom*)ttls;
    }
    else if(strcasecmp(my_name,"analogout")==0) {
        XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&my_name);
        analogout* aout=new analogout();
        // read parameters
        char* channel=get_parameter(element,"channel","c","id","i",(char*)NULL);
        if (channel!=NULL) {
            aout->id=strtoul(channel,NULL,0);
            XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&channel);
        }
        char* frequency=get_parameter(element,"frequency","f",(char*)NULL);
        if (frequency!=NULL) {
            aout->frequency=strtod(frequency,NULL);
            XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&frequency);
        }
        char* dac_value=get_parameter(element,"dac_value","d",(char*)NULL);
        if (dac_value!=NULL) {
            aout->dac_value=strtol(dac_value,NULL,0);
            XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&dac_value);
        }

        char* phase=get_parameter(element,"phase","p",(char*)NULL);
        if (phase!=NULL) {
            aout->phase=strtod(phase,NULL);
            XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&phase);
        }
        char* amplitude=get_parameter(element,"amplitude","a",(char*)NULL);
        if (amplitude!=NULL) {
            aout->amplitude=strtod(amplitude,NULL);
            XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&amplitude);
        }
        else
            aout->amplitude=1.0;
        return aout;
    }
    else if(strcasecmp(my_name,"analogin")==0) {
        XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&my_name);
        analogin* ain=new analogin();
        // read parameters
        char* id=get_parameter(element,"id","i",(char*)NULL);
        if (id!=NULL) {
            ain->id=strtoul(id,NULL,0);
            XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&id);
        }
        char* frequency=get_parameter(element,"f","frequency",(char*)NULL);
        if (frequency!=NULL) {
            ain->sample_frequency=strtod(frequency,NULL);
            XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&frequency);
            if (ain->sample_frequency<0) {
                delete ain;
                throw job_exception("frequency must be non-negative");
            }
        }
        char* samples=get_parameter(element,"s","samples",(char*)NULL);
        if (samples!=NULL) {
            char* samples_startpos=samples;
            while (*samples_startpos!=0 && isspace(*samples_startpos)) ++samples_startpos;
            if (*samples_startpos=='-') {
                XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&samples);
                delete ain;
                throw job_exception("frequency must be non-negative");
            }
            ain->samples=strtoul(samples,NULL,0);
            XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&samples);
        }
        char* channels=get_parameter(element,"c","channels",(char*)NULL);
        if (channels!=NULL) {
            ain->channels=strtoul(channels,NULL,0);
            XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&channels);
        }
        else
            ain->channels=3;
        char* sensitivity=get_parameter(element,"sen","sensitivity",(char*)NULL);
        if (sensitivity!=NULL) {
            ain->sensitivity=strtod(sensitivity,NULL);
            XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&sensitivity);
        }
        else
            ain->sensitivity=5.0;
        char* resolution=get_parameter(element,"r","res","resolution",(char*)NULL);
        if (resolution!=NULL) {
            ain->resolution=strtoul(resolution,NULL,0);
            XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&resolution);
        }
        else
            ain->resolution=12;

        return (state_atom*)ain;
    }

    return NULL;
}
示例#11
0
文件: job.cpp 项目: ReCodEx/worker
void job::build_job()
{
	// check job info
	if (job_meta_->job_id == "") {
		throw job_exception("Job ID cannot be empty");
	} else if (job_meta_->file_server_url == "") {
		throw job_exception("File server URL cannot be empty");
	} else if (job_meta_->hwgroups.empty()) {
		throw job_exception("Job configuration has no specified hwgroup");
	}

	// check if job is meant to be processed on this worker
	auto hw_group_it = std::find(job_meta_->hwgroups.begin(), job_meta_->hwgroups.end(), worker_config_->get_hwgroup());
	if (hw_group_it == job_meta_->hwgroups.end()) {
		throw job_exception("Job is not supposed to be processed on this worker, hwgroups does not match");
	}

	// create root task, which is logical root of evaluation
	size_t id = 0;
	root_task_ = factory_->create_internal_task(id++);

	// construct all tasks with their ids and check if they have all datas, but do not connect them
	std::map<std::string, std::shared_ptr<task_base>> unconnected_tasks;
	for (auto &task_meta : job_meta_->tasks) {
		if (task_meta->task_id == "") {
			throw job_exception("Task ID cannot be empty");
		} else if (task_meta->priority == 0) {
			throw job_exception("Priority cannot be zero");
		} else if (task_meta->binary == "") {
			throw job_exception("Command cannot be empty");
		}

		// go through variables parsing
		task_meta->binary = parse_job_var(task_meta->binary);
		for (size_t i = 0; i < task_meta->cmd_args.size(); ++i) {
			task_meta->cmd_args.at(i) = parse_job_var(task_meta->cmd_args.at(i));
		}

		std::shared_ptr<task_base> task;

		// distinguish internal/external command and construct suitable object
		if (task_meta->sandbox != nullptr) {

			// //////////////// //
			// external command //
			// //////////////// //

			auto sandbox = task_meta->sandbox;

			if (sandbox->name.empty()) {
				throw job_exception("Sandbox name cannot be empty");
			}

			// first we have to get appropriate hwgroup limits
			std::shared_ptr<sandbox_limits> limits;
			auto hwit = sandbox->loaded_limits.find(worker_config_->get_hwgroup());
			if (hwit != sandbox->loaded_limits.end()) {
				limits = hwit->second;

				// check and maybe modify limits
				process_task_limits(limits);
			} else {
				limits = std::make_shared<sandbox_limits>(worker_config_->get_limits());
			}

			// go through variables parsing
			limits->std_input = parse_job_var(limits->std_input);
			limits->std_output = parse_job_var(limits->std_output);
			limits->std_error = parse_job_var(limits->std_error);
			limits->chdir = parse_job_var(limits->chdir);
			std::vector<std::tuple<std::string, std::string, sandbox_limits::dir_perm>> new_bnd_dirs;
			for (auto &bnd_dir : limits->bound_dirs) {
				new_bnd_dirs.push_back(std::tuple<std::string, std::string, sandbox_limits::dir_perm>{
					parse_job_var(std::get<0>(bnd_dir)), parse_job_var(std::get<1>(bnd_dir)), std::get<2>(bnd_dir)});
			}
			limits->bound_dirs = new_bnd_dirs;

			// ... and finally construct external task from given information
			create_params data = {
				worker_config_->get_worker_id(), id++, task_meta, limits, logger_, working_directory_.string()};

			task = factory_->create_sandboxed_task(data);

		} else {

			// //////////////// //
			// internal command //
			// //////////////// //

			task = factory_->create_internal_task(id++, task_meta);

			if (task == nullptr) {
				throw job_exception("Unknown internal task: " + task_meta->binary);
			}
		}

		// add newly created task to container ready for connect with other tasks
		unconnected_tasks.insert(std::make_pair(task_meta->task_id, task));
	}

	// constructed tasks in map have to have tree structure, so... make it and connect them
	connect_tasks(root_task_, unconnected_tasks);

	// all should be done now... just linear ordering is missing...
	try {
		helpers::topological_sort(root_task_, task_queue_);
	} catch (helpers::top_sort_exception &e) {
		throw job_exception(e.what());
	}

	// remove unnecessary root task from begining of task queue
	if (!task_queue_.empty() && task_queue_.at(0)->get_task_id() == "") {
		task_queue_.erase(task_queue_.begin());
	} else {
		// something bad is happening here, stop this job evaluation
		throw job_exception("Root task not present in first place after topological sort.");
	}
}
示例#12
0
文件: job.cpp 项目: ReCodEx/worker
void job::process_task_limits(std::shared_ptr<sandbox_limits> limits)
{
	if (limits == nullptr) {
		throw job_exception("Internal error. Nullptr dereference in process_task_limits.");
	}

	auto worker_limits = worker_config_->get_limits();
	std::string msg = " item is bigger than default worker value";

	// we have to load defaults from worker_config if necessary and check for bigger limits than in worker_config
	if (limits->cpu_time == FLT_MAX) {
		limits->cpu_time = worker_limits.cpu_time;
	} else {
		if (limits->cpu_time > worker_limits.cpu_time) {
			throw job_exception("time" + msg);
		}
	}
	if (limits->wall_time == FLT_MAX) {
		limits->wall_time = worker_limits.wall_time;
	} else {
		if (limits->wall_time > worker_limits.wall_time) {
			throw job_exception("wall-time" + msg);
		}
	}
	if (limits->extra_time == FLT_MAX) {
		limits->extra_time = worker_limits.extra_time;
	} else {
		if (limits->extra_time > worker_limits.extra_time) {
			throw job_exception("extra-time" + msg);
		}
	}
	if (limits->stack_size == SIZE_MAX) {
		limits->stack_size = worker_limits.stack_size;
	} else {
		if (limits->stack_size > worker_limits.stack_size) {
			throw job_exception("stack-size" + msg);
		}
	}
	if (limits->memory_usage == SIZE_MAX) {
		limits->memory_usage = worker_limits.memory_usage;
	} else {
		if (limits->memory_usage > worker_limits.memory_usage) {
			throw job_exception("memory" + msg);
		}
	}
	if (limits->processes == SIZE_MAX) {
		limits->processes = worker_limits.processes;
	} else {
		if (limits->processes > worker_limits.processes) {
			throw job_exception("parallel" + msg);
		}
	}
	if (limits->disk_size == SIZE_MAX) {
		limits->disk_size = worker_limits.disk_size;
	} else {
		if (limits->disk_size > worker_limits.disk_size) {
			throw job_exception("disk-size" + msg);
		}
	}
	if (limits->disk_files == SIZE_MAX) {
		limits->disk_files = worker_limits.disk_files;
	} else {
		if (limits->disk_files > worker_limits.disk_files) {
			throw job_exception("disk-files" + msg);
		}
	}

	// union of bound directories and environs from worker configuration and job configuration
	limits->environ_vars.insert(
		limits->environ_vars.end(), worker_limits.environ_vars.begin(), worker_limits.environ_vars.end());
	limits->bound_dirs.insert(
		limits->bound_dirs.end(), worker_limits.bound_dirs.begin(), worker_limits.bound_dirs.end());
}