27#include <boost/algorithm/string/replace.hpp>
28#include <boost/date_time/posix_time/posix_time.hpp>
29#include <boost/format.hpp>
42template <
typename JobContainer>
47 Job *jobToProc =
nullptr;
50 <<
"Requesting next job" << std::flush;
59 <<
"Sync did not yield any new jobs." << std::flush;
64 if (nextjit_ == jobsToProc_.end()) {
65 if (maxJobs_ == startJobsCount_) {
67 <<
"Next job: ID = - (reached maximum for this process)"
71 <<
"Next job: ID = - (none available)" << std::flush;
76 jobToProc = *nextjit_;
79 <<
"Next job: ID = " << jobToProc->getId() << std::flush;
82 if (!thread.isMaverick() && jobToProc !=
nullptr) {
83 Index idx = jobToProc->getId();
84 Index frac = (jobs_.size() >= 10) ? 10 : jobs_.size();
85 Index rounded =
Index(
double(jobs_.size()) /
double(frac)) * frac;
86 Index tenth = rounded / frac;
87 if (idx % tenth == 0) {
88 double percent = double(idx) / double(rounded) * 100 + 0.5;
89 std::cout << (format(
"=> [%1$2.0f%%] ") % percent).str() << std::flush;
97template <
typename JobContainer>
102 <<
"Reporting job results" << std::flush;
104 job.UpdateFromResult(res);
109 if (!thread.isMaverick()) {
110 std::cout << std::endl << thread.getLogger() << std::flush;
116template <
typename JobContainer>
119 (void)gethostname(host,
sizeof host);
120 pid_t pid = getpid();
121 return (format(
"%1$s:%2$d") % host % pid).str();
124template <
typename JobContainer>
126 boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
127 return (format(
"%1$s") % now.time_of_day()).str();
130template <
typename JobContainer>
137 std::string progBackFile =
progFile_ +
"~";
141 <<
"Update internal structures from job file" << std::flush;
142 JobContainer jobs_ext =
LOAD_JOBS(progFile);
147 <<
"Create job-file back-up" << std::flush;
152 <<
"Assign jobs from stack" << std::flush;
161 bool startJob =
false;
190template <
typename JobContainer>
192 flock_ = std::unique_ptr<boost::interprocess::file_lock>(
193 new boost::interprocess::file_lock(
lockFile_.c_str()));
196 <<
"Imposed lock on " <<
lockFile_ << std::flush;
198 <<
"Sleep ... " <<
lockFile_ << std::flush;
200 <<
"Wake up ... " <<
lockFile_ << std::flush;
203template <
typename JobContainer>
205 flock_->unlock_sharable();
207 <<
"Releasing " <<
lockFile_ <<
". " << std::flush;
210template <
typename JobContainer>
212 const boost::program_options::variables_map &optsMap) {
214 lockFile_ = optsMap[
"file"].as<std::string>();
217 std::string restartPattern = optsMap[
"restart"].as<std::string>();
220 boost::algorithm::replace_all(restartPattern,
" ",
"");
221 if (restartPattern ==
"") {
227 std::vector<std::string> patterns =
230 std::string category =
"";
231 for (
const std::string &pattern : patterns) {
233 if (pattern ==
"host" || pattern ==
"stat") {
236 }
else if (category ==
"host") {
238 }
else if (category ==
"stat") {
239 if (pattern ==
"ASSIGNED" || pattern ==
"COMPLETE") {
240 std::cout <<
"Restart if status == " << pattern
241 <<
"? Not necessarily a good idea." << std::endl;
247 throw std::runtime_error(
248 "Restart pattern ill-defined, format is"
249 "[host([HOSTNAME:PID])] [stat([STATUS])]");
255template <
typename JobContainer>
265 <<
"lock file = '" <<
lockFile_ <<
"', ";
267 <<
"cache size = " <<
cacheSize_ << std::flush;
270 <<
"Initialize jobs from " << progFile << std::flush;
284 <<
"Registered " <<
jobs_.size() <<
" jobs." << std::flush;
285 if (
jobs_.size() > 0) {
293 std::string infostr =
"Restart if host == ";
294 for (
const std::pair<const std::string, bool> &host :
restart_hosts_) {
295 infostr += host.first +
" ";
300 std::string infostr =
"Restart if stat == ";
301 for (
const std::pair<const std::string, bool> &host :
restart_hosts_) {
302 infostr += host.first +
" ";
void LockProgFile(QMThread &thread)
typename JobContainer::value_type Job
std::vector< Job * > jobsToProc_
void InitFromProgFile(std::string progFile, QMThread &thread)
void ReportJobDone(Job &job, Result &res, QMThread &thread)
ProgObserver::Job * RequestNextJob(QMThread &thread)
std::string GenerateTime()
typename Job::JobResult Result
std::map< std::string, bool > restart_stats_
std::map< std::string, bool > restart_hosts_
std::string GenerateHost()
void ReleaseProgFile(QMThread &thread)
void SyncWithProgFile(QMThread &thread)
void InitCmdLineOpts(const boost::program_options::variables_map &optsMap)
std::unique_ptr< boost::interprocess::file_lock > flock_
#define XTP_LOG(level, log)
Charge transport classes.
void WRITE_JOBS(const std::vector< Job > &jobs, const std::string &job_file)
void UPDATE_JOBS(const std::vector< Job > &from, std::vector< Job > &to, const std::string &thisHost)
std::vector< Job > LOAD_JOBS(const std::string &xml_file)
Provides a means for comparing floating point numbers.