Back to index

nordugrid-arc-nox  1.1.0~rc6
JobSupervisor.cpp
Go to the documentation of this file.
00001 // -*- indent-tabs-mode: nil -*-
00002 
00003 #ifdef HAVE_CONFIG_H
00004 #include <config.h>
00005 #endif
00006 
00007 #include <algorithm>
00008 #include <iostream>
00009 
00010 #include <arc/ArcConfig.h>
00011 #include <arc/FileLock.h>
00012 #include <arc/Logger.h>
00013 #include <arc/StringConv.h>
00014 #include <arc/XMLNode.h>
00015 #include <arc/client/JobController.h>
00016 #include <arc/client/JobSupervisor.h>
00017 #include <arc/client/ClientInterface.h>
00018 #include <arc/UserConfig.h>
00019 
00020 namespace Arc {
00021 
00022   Logger JobSupervisor::logger(Logger::getRootLogger(), "JobSupervisor");
00023 
00024   JobSupervisor::JobSupervisor(const UserConfig& usercfg,
00025                                const std::list<std::string>& jobs)
00026     : jobsFound(false) {
00027     URLListMap jobids;
00028 
00029     Config jobstorage;
00030     if (!usercfg.JobListFile().empty()) {
00031       FileLock lock(usercfg.JobListFile());
00032       jobstorage.ReadFromFile(usercfg.JobListFile());
00033     }
00034 
00035     std::list<std::string> controllers;
00036 
00037     if (!jobs.empty()) {
00038 
00039       logger.msg(VERBOSE, "Identifying needed job controllers according to "
00040                  "specified jobs");
00041 
00042       for (std::list<std::string>::const_iterator it = jobs.begin();
00043            it != jobs.end(); it++) {
00044         std::string strJobID = *it;
00045         // Remove trailing slashes '/'.
00046         const std::string::size_type pos = strJobID.find_last_not_of("/");
00047         if (pos != std::string::npos)
00048           strJobID = strJobID.substr(0, pos + 1);
00049 
00050         XMLNodeList xmljobs =
00051           jobstorage.XPathLookup("//Job[JobID='" + strJobID + "' or "
00052                                  "Name='" + *it + "']", NS());
00053 
00054         if (xmljobs.empty()) {
00055           logger.msg(WARNING, "Job not found in job list: %s", *it);
00056           continue;
00057         }
00058         else
00059           jobsFound = true;
00060 
00061         for (XMLNodeList::iterator xit = xmljobs.begin();
00062              xit != xmljobs.end(); xit++) {
00063           const std::string flavour = (std::string)(*xit)["Flavour"];
00064           jobids[flavour].push_back((std::string)(*xit)["JobID"]);
00065 
00066           if (std::find(controllers.begin(), controllers.end(),
00067                         flavour) == controllers.end()) {
00068             logger.msg(VERBOSE, "Need job controller for grid flavour %s",
00069                        flavour);
00070             controllers.push_back(flavour);
00071           }
00072         }
00073       }
00074     }
00075 
00076     if (!usercfg.GetSelectedServices(COMPUTING).empty()) {
00077 
00078       logger.msg(VERBOSE, "Identifying needed job controllers according to "
00079                  "specified clusters");
00080 
00081       for (URLListMap::const_iterator it = usercfg.GetSelectedServices(COMPUTING).begin();
00082            it != usercfg.GetSelectedServices(COMPUTING).end(); it++) {
00083         if (std::find(controllers.begin(), controllers.end(),
00084                       it->first) == controllers.end()) {
00085           std::list<URL>::const_iterator itCluster = it->second.begin();
00086           for (; itCluster != it->second.end(); itCluster++)
00087             if (jobstorage.XPathLookup("//Job[Cluster='" + itCluster->str() + "']", NS()).size() > 0)
00088               break;
00089 
00090           if (itCluster == it->second.end()) // No jobs found at the specified cluster.
00091             break;
00092 
00093           jobsFound = true;
00094           logger.msg(VERBOSE, "Need job controller for grid flavour %s",
00095                      it->first);
00096           controllers.push_back(it->first);
00097         }
00098       }
00099     }
00100 
00101     if (jobs.empty() && usercfg.GetSelectedServices(COMPUTING).empty()) {
00102 
00103       logger.msg(VERBOSE, "Identifying needed job controllers according to "
00104                  "all jobs present in job list");
00105 
00106       XMLNodeList xmljobs = jobstorage.Path("Job");
00107 
00108       if (xmljobs.empty())
00109         return;
00110 
00111       jobsFound = true;
00112 
00113       for (XMLNodeList::iterator it = xmljobs.begin();
00114            it != xmljobs.end(); it++)
00115         if (std::find(controllers.begin(), controllers.end(),
00116                       (std::string)(*it)["Flavour"]) == controllers.end()) {
00117           std::string flavour = (*it)["Flavour"];
00118           logger.msg(VERBOSE, "Need job controller for grid flavour %s",
00119                      flavour);
00120           controllers.push_back(flavour);
00121         }
00122     }
00123 
00124     for (std::list<std::string>::iterator it = controllers.begin();
00125          it != controllers.end(); it++) {
00126       JobController *JC = loader.load(*it, usercfg);
00127       if (JC)
00128         JC->FillJobStore(jobids[*it]);
00129     }
00130   }
00131 
00132   JobSupervisor::~JobSupervisor() {}
00133 
00134 } // namespace Arc