Salome HOME
Correction of bug that make the YACSContainer crash when container log is requested...
[modules/yacs.git] / src / runtime / PythonNode.cxx
index 82cfb19e91fcee467faee2034c0b981704128e20..e8cbc26248a5a640f154355bd4dfc214cc51af0e 100644 (file)
@@ -75,12 +75,12 @@ PythonEntry::~PythonEntry()
 {
   AutoGIL agil;
   DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
-  Py_XDECREF(_pyfuncUnser);
-  Py_XDECREF(_pyfuncSer);
+  // not Py_XDECREF of _pyfuncUnser because it is returned by PyDict_GetItem -> borrowed
+  // not Py_XDECREF of _pyfuncSer because it is returned by PyDict_GetItem -> borrowed
   Py_XDECREF(_context);
 }
 
-void PythonEntry::commonRemoteLoad(InlineNode *reqNode)
+void PythonEntry::commonRemoteLoadPart1(InlineNode *reqNode)
 {
   DEBTRACE( "---------------PythonEntry::CommonRemoteLoad function---------------" );
   Container *container(reqNode->getContainer());
@@ -108,6 +108,11 @@ void PythonEntry::commonRemoteLoad(InlineNode *reqNode)
       reqNode->setErrorDetails(what);
       throw Exception(what);
     }
+}
+
+Engines::Container_var PythonEntry::commonRemoteLoadPart2(InlineNode *reqNode, bool& isInitializeRequested)
+{
+  Container *container(reqNode->getContainer());
   Engines::Container_var objContainer=Engines::Container::_nil();
   if(!container)
     throw Exception("No container specified !");
@@ -124,7 +129,7 @@ void PythonEntry::commonRemoteLoad(InlineNode *reqNode)
     throw Exception("Unrecognized type of container ! Salome one is expected for PythonNode/PyFuncNode !");
   if(CORBA::is_nil(objContainer))
     throw Exception("Container corba pointer is NULL for PythonNode !");
-  bool isInitializeRequested(false);
+  isInitializeRequested=false;
   try
   {
       if(containerCast0)
@@ -154,66 +159,116 @@ void PythonEntry::commonRemoteLoad(InlineNode *reqNode)
   Engines::PyNodeBase_var pynode(getRemoteInterpreterHandle());
   if(CORBA::is_nil(pynode))
     throw Exception("In PythonNode the ref in NULL ! ");
+  return objContainer;
+}
+
+void PythonEntry::commonRemoteLoadPart3(InlineNode *reqNode, Engines::Container_ptr objContainer, bool isInitializeRequested)
+{
+  Container *container(reqNode->getContainer());
+  Engines::PyNodeBase_var pynode(getRemoteInterpreterHandle());
   ///
   {
-      AutoGIL agil;
-      const char *picklizeScript(getSerializationScript());
-      PyObject *res=PyRun_String(picklizeScript,Py_file_input,_context,_context);
-      if(res == NULL)
+    AutoGIL agil;
+    const char *picklizeScript(getSerializationScript());
+    PyObject *res=PyRun_String(picklizeScript,Py_file_input,_context,_context);
+    if(res == NULL)
+      {
+        std::string errorDetails;
+        PyObject* new_stderr = newPyStdOut(errorDetails);
+        reqNode->setErrorDetails(errorDetails);
+        PySys_SetObject((char*)"stderr", new_stderr);
+        PyErr_Print();
+        PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
+        Py_DECREF(new_stderr);
+        throw Exception("Error during load");
+      }
+    Py_DECREF(res);
+    _pyfuncSer=PyDict_GetItemString(_context,"pickleForDistPyth2009");
+    _pyfuncUnser=PyDict_GetItemString(_context,"unPickleForDistPyth2009");
+    if(_pyfuncSer == NULL)
+      {
+        std::string errorDetails;
+        PyObject *new_stderr(newPyStdOut(errorDetails));
+        reqNode->setErrorDetails(errorDetails);
+        PySys_SetObject((char*)"stderr", new_stderr);
+        PyErr_Print();
+        PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
+        Py_DECREF(new_stderr);
+        throw Exception("Error during load");
+      }
+    if(_pyfuncUnser == NULL)
+      {
+        std::string errorDetails;
+        PyObject *new_stderr(newPyStdOut(errorDetails));
+        reqNode->setErrorDetails(errorDetails);
+        PySys_SetObject((char*)"stderr", new_stderr);
+        PyErr_Print();
+        PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
+        Py_DECREF(new_stderr);
+        throw Exception("Error during load");
+      }
+  }
+  if(isInitializeRequested)
+    {//This one is called only once at initialization in the container if an init-script is specified.
+      try
+      {
+          std::string zeInitScriptKey(container->getProperty(HomogeneousPoolContainer::INITIALIZE_SCRIPT_KEY));
+          if(!zeInitScriptKey.empty())
+            pynode->executeAnotherPieceOfCode(zeInitScriptKey.c_str());
+      }
+      catch( const SALOME::SALOME_Exception& ex )
+      {
+          std::string msg="Exception on PythonNode::loadRemote python invocation of initializisation py script !";
+          msg += '\n';
+          msg += ex.details.text.in();
+          reqNode->setErrorDetails(msg);
+          throw Exception(msg);
+      }
+      DEBTRACE( "---------------End PyNode::loadRemote function---------------" );
+    }
+}
+
+std::string PythonEntry::GetContainerLog(const std::string& mode, Container *container, const Task *askingTask)
+{
+  if(mode=="local")
+    return "";
+
+  std::string msg;
+  try
+  {
+      SalomeContainer *containerCast(dynamic_cast<SalomeContainer *>(container));
+      SalomeHPContainer *objContainer2(dynamic_cast<SalomeHPContainer *>(container));
+      if(containerCast)
         {
-          std::string errorDetails;
-          PyObject* new_stderr = newPyStdOut(errorDetails);
-          reqNode->setErrorDetails(errorDetails);
-          PySys_SetObject((char*)"stderr", new_stderr);
-          PyErr_Print();
-          PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
-          Py_DECREF(new_stderr);
-          throw Exception("Error during load");
+          Engines::Container_var objContainer(containerCast->getContainerPtr(askingTask));
+          CORBA::String_var logname = objContainer->logfilename();
+          DEBTRACE(logname);
+          msg=logname;
+          std::string::size_type pos = msg.find(":");
+          msg=msg.substr(pos+1);
         }
-      Py_DECREF(res);
-      _pyfuncSer=PyDict_GetItemString(_context,"pickleForDistPyth2009");
-      _pyfuncUnser=PyDict_GetItemString(_context,"unPickleForDistPyth2009");
-      if(_pyfuncSer == NULL)
+      else if(objContainer2)
         {
-          std::string errorDetails;
-          PyObject *new_stderr(newPyStdOut(errorDetails));
-          reqNode->setErrorDetails(errorDetails);
-          PySys_SetObject((char*)"stderr", new_stderr);
-          PyErr_Print();
-          PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
-          Py_DECREF(new_stderr);
-          throw Exception("Error during load");
+          msg="Remote PythonNode is on HP Container : no log because no info of the location by definition of HP Container !";
         }
-      if(_pyfuncUnser == NULL)
+      else
         {
-          std::string errorDetails;
-          PyObject *new_stderr(newPyStdOut(errorDetails));
-          reqNode->setErrorDetails(errorDetails);
-          PySys_SetObject((char*)"stderr", new_stderr);
-          PyErr_Print();
-          PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
-          Py_DECREF(new_stderr);
-          throw Exception("Error during load");
+          msg="Not implemented yet for container log for that type of container !";
         }
-      if(isInitializeRequested)
-        {//This one is called only once at initialization in the container if an init-script is specified.
-          try
-          {
-              std::string zeInitScriptKey(container->getProperty(HomogeneousPoolContainer::INITIALIZE_SCRIPT_KEY));
-              if(!zeInitScriptKey.empty())
-                pynode->executeAnotherPieceOfCode(zeInitScriptKey.c_str());
-          }
-          catch( const SALOME::SALOME_Exception& ex )
-          {
-              std::string msg="Exception on PythonNode::loadRemote python invocation of initializisation py script !";
-              msg += '\n';
-              msg += ex.details.text.in();
-              reqNode->setErrorDetails(msg);
-              throw Exception(msg);
-          }
-        }
-      DEBTRACE( "---------------End PyNode::loadRemote function---------------" );
   }
+  catch(...)
+  {
+      msg = "Container no longer reachable";
+  }
+  return msg;
+}
+
+void PythonEntry::commonRemoteLoad(InlineNode *reqNode)
+{
+  commonRemoteLoadPart1(reqNode);
+  bool isInitializeRequested;
+  Engines::Container_var objContainer(commonRemoteLoadPart2(reqNode,isInitializeRequested));
+  commonRemoteLoadPart3(reqNode,objContainer,isInitializeRequested);
 }
 
 PythonNode::PythonNode(const PythonNode& other, ComposedNode *father):InlineNode(other,father)
@@ -312,6 +367,14 @@ void PythonNode::executeRemote()
   DEBTRACE( "++++++++++++++ PyNode::executeRemote: " << getName() << " ++++++++++++++++++++" );
   if(!_pyfuncSer)
     throw Exception("DistributedPythonNode badly loaded");
+  //
+  if(dynamic_cast<HomogeneousPoolContainer *>(getContainer()))
+    {
+      bool dummy;
+      commonRemoteLoadPart2(this,dummy);
+      _pynode->assignNewCompiledCode(getScript().c_str());
+    }
+  //
   Engines::pickledArgs_var serializationInputCorba(new Engines::pickledArgs);
   {
       AutoGIL agil;
@@ -557,23 +620,7 @@ void PythonNode::executeLocal()
 
 std::string PythonNode::getContainerLog()
 {
-  if(_mode=="local")return "";
-
-  std::string msg;
-  try
-    {
-      Engines::Container_var objContainer=((SalomeContainer*)_container)->getContainerPtr(this);
-      CORBA::String_var logname = objContainer->logfilename();
-      DEBTRACE(logname);
-      msg=logname;
-      std::string::size_type pos = msg.find(":");
-      msg=msg.substr(pos+1);
-    }
-  catch(...)
-    {
-      msg = "Container no longer reachable";
-    }
-  return msg;
+  return PythonEntry::GetContainerLog(_mode,_container,this);
 }
 
 void PythonNode::shutdown(int level)
@@ -818,6 +865,14 @@ void PyFuncNode::executeRemote()
   DEBTRACE( "++++++++++++++ PyFuncNode::executeRemote: " << getName() << " ++++++++++++++++++++" );
   if(!_pyfuncSer)
     throw Exception("DistributedPythonNode badly loaded");
+  //
+  if(dynamic_cast<HomogeneousPoolContainer *>(getContainer()))
+    {
+      bool dummy;
+      commonRemoteLoadPart2(this,dummy);
+      _pynode->executeAnotherPieceOfCode(getScript().c_str());
+    }
+  //
   Engines::pickledArgs_var serializationInputCorba(new Engines::pickledArgs);;
   {
       AutoGIL agil;
@@ -1111,23 +1166,7 @@ PyFuncNode* PyFuncNode::cloneNode(const std::string& name)
 
 std::string PyFuncNode::getContainerLog()
 {
-  if(_mode=="local")return "";
-
-  std::string msg;
-  try
-    {
-      Engines::Container_var objContainer=((SalomeContainer*)_container)->getContainerPtr(this);
-      CORBA::String_var logname = objContainer->logfilename();
-      DEBTRACE(logname);
-      msg=logname;
-      std::string::size_type pos = msg.find(":");
-      msg=msg.substr(pos+1);
-    }
-  catch(...)
-    {
-      msg = "Container no longer reachable";
-    }
-  return msg;
+  return PythonEntry::GetContainerLog(_mode,_container,this);
 }
 
 void PyFuncNode::shutdown(int level)