Salome HOME
Fix crushing when asking the error report in ydefx.
[modules/yacs.git] / src / evalyfx / YACSEvalYFXPattern.cxx
index 3c00612bf3222eacf19f6cd3090d916a2ba013f6..1ab3d00d2f880f2ce985541dc61f6f8d46bc40c3 100644 (file)
@@ -25,6 +25,7 @@
 #include "YACSEvalObserver.hxx"
 #include "YACSEvalSessionInternal.hxx"
 #include "YACSEvalAutoPtr.hxx"
+#include "YACSEvalExecParams.hxx"
 
 #include "ElementaryNode.hxx"
 #include "RuntimeSALOME.hxx"
@@ -34,6 +35,7 @@
 #include "LinkInfo.hxx"
 #include "TypeCode.hxx"
 #include "Proc.hxx"
+#include "Dispatcher.hxx"
 
 #include "PythonPorts.hxx"
 #include "ForEachLoop.hxx"
@@ -71,9 +73,21 @@ const char YACSEvalYFXGraphGen::GATHER_NODE_NAME[]="__gather__";
 class MyAutoThreadSaver
 {
 public:
-  MyAutoThreadSaver():_save(PyEval_SaveThread()) { }
-  ~MyAutoThreadSaver() { PyEval_RestoreThread(_save); }
+  MyAutoThreadSaver(bool isToSave):_isToSave(isToSave),_save(0)
+  {
+    if(_isToSave)
+      {
+        PyThreadState *save(PyThreadState_Swap(NULL));// safe call of PyEval_SaveThread()
+        if(save)
+          {
+            _save=save;
+            PyEval_ReleaseLock();
+          }
+      }
+  }
+  ~MyAutoThreadSaver() { if(_isToSave) if(_save) { PyEval_AcquireLock(); PyThreadState_Swap(_save); /*safe call of PyEval_RestoreThread*/ } }
 private:
+  bool _isToSave;
   PyThreadState *_save;
 };
 
@@ -296,21 +310,29 @@ class YACSEvalYFXRunOnlyPatternInternalObserver : public YACS::ENGINE::Observer
 {
 public:
   YACSEvalYFXRunOnlyPatternInternalObserver(YACSEvalYFXRunOnlyPattern *boss):_boss(boss) { if(!_boss) throw YACS::Exception("YACSEvalYFXRunOnlyPatternInternalObserver constructor : null boss not supported :)"); }
-  void notifyObserver(YACS::ENGINE::Node *object, const std::string& event);
+  void notifyObserver2(YACS::ENGINE::Node *object, const std::string& event, void *something);
 private:
   YACSEvalYFXRunOnlyPattern *_boss;
 };
 
-void YACSEvalYFXRunOnlyPatternInternalObserver::notifyObserver(YACS::ENGINE::Node *object, const std::string& event)
+void YACSEvalYFXRunOnlyPatternInternalObserver::notifyObserver2(YACS::ENGINE::Node *object, const std::string& event, void *something)
 {
-  YACS::ENGINE::ForEachLoop *object2(dynamic_cast<YACS::ENGINE::ForEachLoop *>(object));
-  if(!object2)
-    return ;
+  YACS::ENGINE::ForEachLoop *object2(_boss->getUndergroundForEach());
   YACSEvalObserver *obs(_boss->getObserver());
   if(!obs)
     return ;
-  if(event=="progress")
-    obs->notifyNewNumberOfPassedItems(_boss->getBoss(),object2->getCurrentIndex());
+  if(event=="progress_ok" && object2==object)
+    {
+      int *casted(reinterpret_cast<int *>(something));
+      obs->notifySampleOK(_boss->getBoss(),*casted);
+      return ;
+    }
+  if(event=="progress_ko" && object2==object)
+    {
+      int *casted(reinterpret_cast<int *>(something));
+      obs->notifySampleKO(_boss->getBoss(),*casted);
+      return ;
+    }
 }
 
 /////////////////////
@@ -407,6 +429,11 @@ YACS::ENGINE::Proc *YACSEvalYFXRunOnlyPattern::getUndergroundGeneratedGraph() co
 
 std::string YACSEvalYFXRunOnlyPattern::getErrorDetailsInCaseOfFailure() const
 {
+  std::string generatorErrors = getGenerator()->getErrors();
+  if(generatorErrors.size() > 0)
+  {
+    return generatorErrors;
+  }
   std::string st(getStatusOfRunStr());//test if a run has occurred.
   if(st==ST_OK)
     throw YACS::Exception("YACSEvalYFXRunOnlyPattern::getErrorDetailsInCaseOfFailure : The execution of scheme has been carried out to the end without any problem !");
@@ -432,14 +459,6 @@ std::string YACSEvalYFXRunOnlyPattern::getErrorDetailsInCaseOfFailure() const
               oss << "NODE = " << nnc->getChildName(*it1) << std::endl;
               oss << "STATUS = " << nsm[st0] << std::endl;
               oss << "BRANCH ID = " << j << std::endl;
-              std::list<YACS::ENGINE::InputPort *> inps((*it1)->getSetOfInputPort());
-              for(std::list<YACS::ENGINE::InputPort *>::const_iterator it2=inps.begin();it2!=inps.end();it2++)
-                {
-                  std::string d((*it2)->getHumanRepr());
-                  if(d.size()>10000)
-                    d=d.substr(0,MAX_LGTH_OF_INP_DUMP);
-                  oss << "INPUT \"" << (*it2)->getName() << "\" = " << d << std::endl;
-                }
               oss << "DETAILS = " << std::endl;
               oss << (*it1)->getErrorDetails();
             }
@@ -546,13 +565,19 @@ void YACSEvalYFXRunOnlyPattern::emitStart() const
   YACSEvalObserver *obs(getObserver());
   if(!obs)
     return ;
-  obs->notifyNumberOfSamplesToEval(getBoss(),getUndergroundForEach()->getNbOfElementsToBeProcessed());
+  obs->startComputation(getBoss());
 }
 
-bool YACSEvalYFXRunOnlyPattern::go(bool stopASAP, YACSEvalSession *session) const
+bool YACSEvalYFXRunOnlyPattern::go(const YACSEvalExecParams& params, YACSEvalSession *session) const
 {
   emitStart();
-  return getGenerator()->go(stopASAP,session);
+  YACS::ENGINE::Dispatcher *disp(YACS::ENGINE::Dispatcher::getDispatcher());
+  disp->addObserver(_obs,getUndergroundForEach(),"progress_ok");
+  disp->addObserver(_obs,getUndergroundForEach(),"progress_ko");
+  bool ret(getGenerator()->go(params,session));
+  disp->removeObserver(_obs,getUndergroundForEach(),"progress_ok");
+  disp->removeObserver(_obs,getUndergroundForEach(),"progress_ko");
+  return ret;
 }
 
 YACS::ENGINE::ForEachLoop *YACSEvalYFXRunOnlyPattern::getUndergroundForEach() const
@@ -791,17 +816,22 @@ void YACSEvalYFXGraphGenInteractive::generateGraph()
   _generatedGraph->updateContainersAndComponents();
 }
 
-bool YACSEvalYFXGraphGenInteractive::go(bool stopASAP, YACSEvalSession *session) const
+bool YACSEvalYFXGraphGenInteractive::go(const YACSEvalExecParams& params, YACSEvalSession *session) const
 {
   YACS::ENGINE::Executor exe;
-  exe.setKeepGoingProperty(!stopASAP);
+  exe.setKeepGoingProperty(!params.getStopASAPAfterErrorStatus());
   {
-    MyAutoThreadSaver locker;
+    MyAutoThreadSaver locker(!session->isAlreadyPyThreadSaved());
     exe.RunW(getUndergroundGeneratedGraph());
   }
   return getUndergroundGeneratedGraph()->getState()==YACS::DONE;
 }
 
+std::string YACSEvalYFXGraphGenInteractive::getErrors()const
+{
+  return "";
+}
+
 std::vector<YACSEvalSeqAny *> YACSEvalYFXGraphGenInteractive::getResults() const
 {
   if(getUndergroundGeneratedGraph()->getState()!=YACS::DONE)
@@ -831,12 +861,13 @@ std::vector<YACSEvalSeqAny *> YACSEvalYFXGraphGenInteractive::getResults() const
 
 void YACSEvalYFXGraphGenCluster::generateGraph()
 {
+  YACS::ENGINE::AutoGIL agil;
   if(_generatedGraph)
     { delete _generatedGraph; _generatedGraph=0; _FEInGeneratedGraph=0; }
   //
   const char EFXGenFileName[]="EFXGenFileName";
-  const char EFXGenContent[]="import getpass,datetime,os\nn=datetime.datetime.now()\nreturn os.path.join(os.path.sep,\"tmp\",\"EvalYFX_%s_%s_%s.xml\"%(getpass.getuser(),n.strftime(\"%d%b%y\"),n.strftime(\"%H%M%S\")))";
-  const char EFXGenContent2[]="import getpass,datetime\nn=datetime.datetime.now()\nreturn \"EvalYFX_%s_%s_%s\"%(getpass.getuser(),n.strftime(\"%d%b%y\"),n.strftime(\"%H%M%S\"))";
+  const char EFXGenContent[]="import getpass,datetime,os\nn=datetime.datetime.now()\nreturn os.path.join(os.path.sep,\"tmp\",\"EvalYFX_%s_%s_%s.xml\"%(getpass.getuser(),n.strftime(\"%d%m%y\"),n.strftime(\"%H%M%S\")))";
+  const char EFXGenContent2[]="import getpass,datetime\nn=datetime.datetime.now()\nreturn \"EvalYFX_%s_%s_%s\"%(getpass.getuser(),n.strftime(\"%d%m%y\"),n.strftime(\"%H%M%S\"))";
   //
   YACS::ENGINE::AutoPyRef func(YACS::ENGINE::evalPy(EFXGenFileName,EFXGenContent));
   YACS::ENGINE::AutoPyRef val(YACS::ENGINE::evalFuncPyWithNoParams(func));
@@ -927,8 +958,10 @@ void YACSEvalYFXGraphGenCluster::generateGraph()
   _generatedGraph->updateContainersAndComponents();
 }
 
-bool YACSEvalYFXGraphGenCluster::go(bool stopASAP, YACSEvalSession *session) const
+bool YACSEvalYFXGraphGenCluster::go(const YACSEvalExecParams& params, YACSEvalSession *session) const
 {
+  YACS::ENGINE::AutoGIL agil;
+  _errors = "";
   getUndergroundGeneratedGraph()->saveSchema(_locSchemaFile);
   YACSEvalListOfResources *rss(getBoss()->getResourcesInternal());
   const YACSEvalParamsForCluster& cli(rss->getAddParamsForCluster());
@@ -955,7 +988,15 @@ bool YACSEvalYFXGraphGenCluster::go(bool stopASAP, YACSEvalSession *session) con
   jp.job_type=CORBA::string_dup("yacs_file");
   jp.job_file=CORBA::string_dup(_locSchemaFile.c_str());
   jp.env_file=CORBA::string_dup("");
-  jp.in_files.length(0);
+  jp.in_files.length(cli.getInFiles().size());
+  std::list<std::string>::const_iterator it;
+  int i;
+  for (it = cli.getInFiles().begin(), i=0 ;
+       it != cli.getInFiles().end();
+       it++, i++)
+  {
+    jp.in_files[i] = CORBA::string_dup((*it).c_str());
+  }
   jp.out_files.length(1);
   jp.out_files[0]=CORBA::string_dup(_jobName.c_str());
   jp.work_directory=CORBA::string_dup(cli.getRemoteWorkingDir().c_str());
@@ -972,7 +1013,21 @@ bool YACSEvalYFXGraphGenCluster::go(bool stopASAP, YACSEvalSession *session) con
   jp.launcher_file=CORBA::string_dup("");
   jp.launcher_args=CORBA::string_dup("");
   _jobid=sl->createJob(jp);
-  sl->launchJob(_jobid);
+  try
+  {
+    sl->launchJob(_jobid);
+  }
+  catch (const SALOME::SALOME_Exception & ex)
+  {
+    _errors = ex.details.text.in();
+    return false;
+  }
+  catch (const CORBA::SystemException& ex)
+  {
+    _errors = "Receive CORBA SystemException.";
+    return false;
+  }
+
   bool ret(false);
   while(true)
     {
@@ -1018,9 +1073,12 @@ bool YACSEvalYFXGraphGenCluster::go(bool stopASAP, YACSEvalSession *session) con
       std::ostringstream oss1; oss1 << "import os" << std::endl << "p=os.path.join(\"" << cli.getLocalWorkingDir() << "\",\"" << _jobName  << "\") ; os.remove(p)" << std::endl;
       std::string s1(oss1.str());
       PyRun_SimpleString(s1.c_str());
-      std::ostringstream oss2; oss2 << "import os,shutil" << std::endl << "p=os.path.join(\"" << cli.getLocalWorkingDir() << "\",\"logs\") ; shutil.rmtree(p)" << std::endl;
-      std::string s2(oss2.str());
-      PyRun_SimpleString(s2.c_str());
+      if(!params.getFetchRemoteDirForClusterStatus())
+        {
+          std::ostringstream oss2; oss2 << "import os,shutil" << std::endl << "p=os.path.join(\"" << cli.getLocalWorkingDir() << "\",\"logs\") ; shutil.rmtree(p)" << std::endl;
+          std::string s2(oss2.str());
+          PyRun_SimpleString(s2.c_str());
+        }
     }
   catch(YACS::Exception& e)
     {
@@ -1031,6 +1089,11 @@ bool YACSEvalYFXGraphGenCluster::go(bool stopASAP, YACSEvalSession *session) con
   return ret;
 }
 
+std::string YACSEvalYFXGraphGenCluster::getErrors()const
+{
+  return _errors;
+}
+
 std::vector<YACSEvalSeqAny *> YACSEvalYFXGraphGenCluster::getResults() const
 {
   std::size_t sz(_res.size());