PluginSupervisor.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2013, Institute for Artificial Intelligence,
00005  *  Universität Bremen.
00006  *  All rights reserved.
00007  *
00008  *  Redistribution and use in source and binary forms, with or without
00009  *  modification, are permitted provided that the following conditions
00010  *  are met:
00011  *
00012  *   * Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *   * Redistributions in binary form must reproduce the above
00015  *     copyright notice, this list of conditions and the following
00016  *     disclaimer in the documentation and/or other materials provided
00017  *     with the distribution.
00018  *   * Neither the name of the Institute for Artificial Intelligence,
00019  *     Universität Bremen, nor the names of its contributors may be
00020  *     used to endorse or promote products derived from this software
00021  *     without specific prior written permission.
00022  *
00023  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00026  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00027  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00028  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00029  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00033  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00034  *  POSSIBILITY OF SUCH DAMAGE.
00035  *********************************************************************/
00036 
00040 #include <plugins/supervisor/PluginSupervisor.h>
00041 
00042 
00043 namespace beliefstate {
00044   namespace plugins {
00045     PLUGIN_CLASS::PLUGIN_CLASS() {
00046       m_bFirstExperiment = true;
00047       this->setPluginVersion("0.6");
00048     }
00049     
00050     PLUGIN_CLASS::~PLUGIN_CLASS() {
00051     }
00052     
00053     Result PLUGIN_CLASS::init(int argc, char** argv) {
00054       Result resInit = defaultResult();
00055       
00056       this->setSubscribedToEvent("startup-complete", true);
00057       this->setSubscribedToEvent("start-new-experiment", true);
00058       this->setSubscribedToEvent("shutdown", true);
00059       
00060       return resInit;
00061     }
00062     
00063     Result PLUGIN_CLASS::deinit() {
00064       // When shutting down, check for .owl files in the experiment
00065       // directory. If there are none, delete the entire experiment
00066       // directory. NOTE(winkler): This might get extended in order
00067       // to support file types in the configuration file. In the
00068       // current state, situations that would only generate .dot
00069       // files (even if this is the desired output) would result in
00070       // a deleted directory. Shouldn't come up at the moment,
00071       // though.
00072       CDesignator* cdIndivConfig = this->getIndividualConfig();
00073       ConfigSettings cfgsetCurrent = configSettings();
00074       
00075       CKeyValuePair* ckvpExtensions = cdIndivConfig->childForKey("experiment-validation-extensions");
00076       
00077       std::list<CKeyValuePair*> lstChildren = ckvpExtensions->children();
00078       std::list<std::string> lstExtensions;
00079       
00080       for(CKeyValuePair* ckvpChild : lstChildren) {
00081         lstExtensions.push_back(ckvpChild->stringValue());
00082       }
00083       
00084       bool bAnyPresent = false;
00085       for(std::string strExt : lstExtensions) {
00086         if(this->extensionPresent(cfgsetCurrent.strExperimentDirectory, strExt)) {
00087           bAnyPresent = true;
00088           
00089           break;
00090         }
00091       }
00092       
00093       if(!bAnyPresent) {
00094         // No validation extensions found in experiment directory.
00095         this->info("Cleaning up directory, as no valid experiment data was found. If this is not what you expected, change your 'experiment-validation-extensions' parameter in the 'supervisor' plugin configuration.");
00096         
00097         deleteDirectory(cfgsetCurrent.strExperimentDirectory);
00098         
00099         std::string strSymlinkName = cfgsetCurrent.strBaseDataDirectory + "/" + cfgsetCurrent.strSymlinkName;
00100         ::remove(strSymlinkName.c_str());
00101       }
00102       
00103       return defaultResult();
00104     }
00105     
00106     Result PLUGIN_CLASS::cycle() {
00107       Result resCycle = defaultResult();
00108       this->deployCycleData(resCycle);
00109       
00110       return resCycle;
00111     }
00112     
00113     bool PLUGIN_CLASS::extensionPresent(std::string strPath, std::string strExtension) {
00114       bool bFound = false;
00115       DIR* dirFile = opendir(strPath.c_str());
00116       std::string strPointExt = "." + strExtension;
00117       
00118       if(dirFile) {
00119         struct dirent* hFile;
00120         errno = 0;
00121         while((hFile = readdir(dirFile)) != NULL) {
00122           if(!strcmp(hFile->d_name, ".")) continue;
00123           if(!strcmp(hFile->d_name, "..")) continue;
00124           
00125           if(strstr(hFile->d_name, strPointExt.c_str())) {
00126             struct stat sb;
00127             std::string strFilepath = strPath + "/" + hFile->d_name;
00128             lstat(strFilepath.c_str(), &sb);
00129             
00130             if((sb.st_mode & S_IFMT) != S_IFLNK) { // Symlinks don't count.
00131               bFound = true;
00132               break;
00133             }
00134           }
00135         }
00136         
00137         closedir(dirFile);
00138       }
00139       
00140       return bFound;
00141     }
00142     
00143     void PLUGIN_CLASS::consumeEvent(Event evEvent) {
00144       if(evEvent.strEventName == "start-new-experiment") {
00145         bool bWait = true;
00146         
00147         // Signal global experiment shut down.
00148         if(m_bFirstExperiment) {
00149           // Only signal an experiment shutdown if this is not the
00150           // first experiment.
00151           m_bFirstExperiment = false;
00152           bWait = false;
00153         } else {
00154           this->deployEvent(defaultEvent("experiment-shutdown"));
00155         }
00156         
00157         if(bWait) {
00158           // Wait 1 sec for all plugins to realize what to do when
00159           // shutting down an experiment.
00160           sleep(1);
00161         }
00162         
00163         ConfigSettings cfgsetCurrent = configSettings();
00164         // Create base data directory
00165         mkdir(cfgsetCurrent.strBaseDataDirectory.c_str(), 0777);
00166         
00167         // This is a hardcoded length. If the length of the
00168         // numeric/date identifier in the string actually exceeds
00169         // this, this will probably result in a segfault. This should
00170         // very rarely be the case, though. We're assuming no problem
00171         // here.
00172         char cName[cfgsetCurrent.strExperimentNameMask.size() + 80];
00173         
00174         std::string strNewName;
00175         std::string strNewExp;
00176         
00177         if(cfgsetCurrent.strExperimentNameMask.find("%d") != string::npos) {
00178           int nIndex = 0;
00179           bool bExists;
00180           
00181           do {
00182             sprintf(cName, (const char*)(cfgsetCurrent.strExperimentNameMask.c_str()), nIndex);
00183             strNewExp = cName;
00184             nIndex++;
00185             
00186             struct stat sb;
00187             int nReturnStat = stat(strNewName.c_str(), &sb);
00188             bExists = (nReturnStat == 0);
00189           } while(bExists);
00190         } else if(cfgsetCurrent.strExperimentNameMask.find("%s") != string::npos) {
00191           std::locale::global(std::locale("en_US.utf8"));
00192           std::time_t t = std::time(NULL);
00193           char cName2[cfgsetCurrent.strExperimentNameMask.size() + 80];
00194           strftime(cName2, cfgsetCurrent.strExperimentNameMask.size() + 80, "%Y-%m-%d_%H-%M-%S", std::localtime(&t));
00195           sprintf(cName, (const char*)(cfgsetCurrent.strExperimentNameMask.c_str()), cName2);
00196           strNewExp = cName;
00197         }
00198         
00199         strNewName = cfgsetCurrent.strBaseDataDirectory + "/" + strNewExp + "/";
00200         mkdir(strNewName.c_str(), 0777);
00201         cfgsetCurrent.strExperimentDirectory = strNewName;
00202         this->info("Created new experiment space: '" + strNewExp + "'.");
00203         setConfigSettings(cfgsetCurrent);
00204         
00205         Event evSetExpNameMeta = defaultEvent("set-experiment-meta-data");
00206         evSetExpNameMeta.cdDesignator = new CDesignator();
00207         evSetExpNameMeta.cdDesignator->setType(ACTION);
00208         evSetExpNameMeta.cdDesignator->setValue("field", "experiment-name");
00209         evSetExpNameMeta.cdDesignator->setValue("value", strNewExp);
00210         this->deployEvent(evSetExpNameMeta);
00211         
00212         std::string strSymlink = cfgsetCurrent.strBaseDataDirectory + "/" + cfgsetCurrent.strSymlinkName;
00213         remove(strSymlink.c_str());
00214         if(symlink(strNewName.c_str(), strSymlink.c_str()) == 0) {
00215           this->info("Symlink set accordingly.");
00216         } else {
00217           this->fail("Unable to set current experiment symlink!");
00218         }
00219         
00220         CDesignator* cdConfig = this->getIndividualConfig();
00221         std::string strKnowRobOwl = cdConfig->stringValue("knowrob-symlink-path");
00222         
00223         if(strKnowRobOwl != "") {
00224           if(symlink(strKnowRobOwl.c_str(), string(strNewName + "knowrob.owl").c_str()) == 0) {
00225             this->info("Created KnowRob OWL symlink to: '" + strKnowRobOwl + "'");
00226           } else {
00227             this->fail("Unable to set KnowRob OWL symlink!");
00228           }
00229         }
00230         
00231         // Signal global experiment start.
00232         this->deployEvent(defaultEvent("experiment-start"));
00233       } else if(evEvent.strEventName == "startup-complete") {
00234         this->deployEvent(defaultEvent("start-new-experiment"));
00235       } else if(evEvent.strEventName == "shutdown") {
00236         this->deployEvent(defaultEvent("experiment-shutdown"));
00237       }
00238     }
00239   }
00240   
00241   extern "C" plugins::PLUGIN_CLASS* createInstance() {
00242     return new plugins::PLUGIN_CLASS();
00243   }
00244   
00245   extern "C" void destroyInstance(plugins::PLUGIN_CLASS* icDestroy) {
00246     delete icDestroy;
00247   }
00248 }


beliefstate
Author(s): Jan Winkler
autogenerated on Sun Oct 5 2014 22:30:15