Salome HOME
[EDF29138] : measure CPU/Mem even in OutOfProcess mode
[modules/kernel.git] / src / Container / SALOME_ContainerManager.cxx
index b8ad494e2982ecf9dbdb9bcf8e6a50f679684dc6..232f47eb1ebe0e07458347a02574b40b029090ed 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2023  CEA, EDF, OPEN CASCADE
+// Copyright (C) 2007-2024  CEA, EDF, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #include "SALOME_ResourcesManager.hxx"
 #include "SALOME_LoadRateManager.hxx"
 #include "SALOME_NamingService.hxx"
+#include "SALOME_Container_i.hxx"
 #include "SALOME_ResourcesManager_Client.hxx"
 #include "SALOME_Embedded_NamingService.hxx"
 #include "SALOME_ModuleCatalog.hh"
 #include "Basics_Utils.hxx"
 #include "Basics_DirUtils.hxx"
 #include "PythonCppUtils.hxx"
+#include "KernelBasis.hxx"
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <signal.h>
@@ -88,9 +90,8 @@ Utils_Mutex SALOME_ContainerManager::_systemMutex;
 //=============================================================================
 
 SALOME_ContainerManager::SALOME_ContainerManager(CORBA::ORB_ptr orb, PortableServer::POA_var poa, SALOME_NamingService_Abstract *ns)
-  : _nbprocUsed(1),_delta_time_ns_lookup_in_ms(DFT_DELTA_TIME_NS_LOOKUP_IN_MS)
+  : _nbprocUsed(1),_delta_time_ns_lookup_in_ms(DFT_DELTA_TIME_NS_LOOKUP_IN_MS),_delta_time_measure_in_ms(Abstract_Engines_Container_i::DFT_TIME_INTERVAL_BTW_MEASURE)
 {
-  MESSAGE("constructor");
   _NS = ns;
   _resManager = new SALOME_ResourcesManager_Client(ns);
   _time_out_in_second = GetTimeOutToLoaunchServer();
@@ -157,8 +158,6 @@ SALOME_ContainerManager::SALOME_ContainerManager(CORBA::ORB_ptr orb, PortableSer
   }
 #endif
 #endif
-
-  MESSAGE("constructor end");
 }
 
 //=============================================================================
@@ -227,15 +226,25 @@ void SALOME_ContainerManager::SetDeltaTimeBetweenNSLookupAtLaunchTimeInMilliSeco
   this->_delta_time_ns_lookup_in_ms = timeInMS;
 }
 
+CORBA::Long SALOME_ContainerManager::GetDeltaTimeBetweenCPUMemMeasureInMilliSecond()
+{
+  return this->_delta_time_measure_in_ms;
+}
+
+void SALOME_ContainerManager::SetDeltaTimeBetweenCPUMemMeasureInMilliSecond(CORBA::Long timeInMS)
+{
+  this->_delta_time_measure_in_ms = timeInMS;
+}
+
 //=============================================================================
 //! Loop on all the containers listed in naming service, ask shutdown on each
 /*! CORBA Method:
  */
 //=============================================================================
 
-void SALOME_ContainerManager::ShutdownContainers()
+void SALOME_ContainerManager::ShutdownContainersGeneric(std::function<void(Engines::Container_ptr)> funcToBeCalledOnContainer)
 {
-  MESSAGE("ShutdownContainers");
+  MESSAGE("ShutdownContainersGeneric");
   if(!_NS)
     return ;
   SALOME::Session_var session = SALOME::Session::_nil();
@@ -281,11 +290,12 @@ void SALOME_ContainerManager::ShutdownContainers()
         Engines::Container_var cont=Engines::Container::_narrow(obj);
         if(!CORBA::is_nil(cont))
         {
-          MESSAGE("ShutdownContainers: " << (*iter));
-          cont->Shutdown();
+          MESSAGE("ShutdownContainersGeneric: " << (*iter));
+          funcToBeCalledOnContainer( cont );
+          MESSAGE("ShutdownContainersGeneric: after call of shutdown" << (*iter));
         }
         else
-          MESSAGE("ShutdownContainers: no container ref for " << (*iter));
+          MESSAGE("ShutdownContainersGeneric: no container ref for " << (*iter));
       }
       catch(CORBA::SystemException& e)
       {
@@ -303,6 +313,26 @@ void SALOME_ContainerManager::ShutdownContainers()
   }
 }
 
+void SALOME_ContainerManager::ShutdownContainers()
+{
+  this->ShutdownContainersGeneric( [](Engines::Container_ptr cont) { cont->Shutdown(); } );
+}
+
+void SALOME_ContainerManager::ShutdownContainersNow()
+{
+  this->ShutdownContainersGeneric( [](Engines::Container_ptr cont)
+  {
+    try
+    {
+      cont->ShutdownNow();
+    }
+    catch(...)
+    {
+    }
+  }
+    );
+}
+
 void SALOME_ContainerManager::SetOverrideEnvForContainers(const Engines::KeyValDict& env)
 {
   this->_override_env.clear();
@@ -324,6 +354,11 @@ Engines::KeyValDict *SALOME_ContainerManager::GetOverrideEnvForContainers()
   return ret.release();
 }
 
+void SALOME_ContainerManager::SetCodeOnContainerStartUp(const char *code)
+{
+  _code_to_exe_on_startup = code;
+}
+
 //=============================================================================
 //! Give a suitable Container given constraints
 /*! CORBA Method:
@@ -484,8 +519,10 @@ Engines::Container_ptr SALOME_ContainerManager::GiveContainer(const Engines::Con
       if (!CORBA::is_nil(cont))
       {
         INFOS("[GiveContainer] container " << containerNameInNS << " launched");
+        cont->monitoringtimeresms( this->_delta_time_measure_in_ms );
+        INFOS("[GiveContainer] container " << containerNameInNS << " first CORBA invocation OK");
         std::ostringstream envInfo;
-        std::for_each( _override_env.begin(), _override_env.end(), [&envInfo](const std::pair<std::string,std::string>& p) { envInfo << p.first << " = " << p.second << std::endl; } );
+        std::for_each( _override_env.begin(), _override_env.end(), [&envInfo](const std::pair<std::string,std::string>& p) { envInfo << p.first << " = " << p.second << " "; } );
         INFOS("[GiveContainer] container " << containerNameInNS << " override " << envInfo.str());
         Engines::FieldsDict envCorba;
         {
@@ -498,6 +535,13 @@ Engines::Container_ptr SALOME_ContainerManager::GiveContainer(const Engines::Con
           }
         }
         cont->override_environment_python( envCorba );
+        if( !_code_to_exe_on_startup.empty() )
+        {
+          INFOS("[GiveContainer] container " << containerNameInNS << " python code executed " << _code_to_exe_on_startup);
+          cont->execute_python_code( _code_to_exe_on_startup.c_str() );
+        }
+        INFOS("[GiveContainer] container " << containerNameInNS << " verbosity positionning Activation = " << SALOME::VerbosityActivated() << " Verbosity Level = " << SALOME::VerbosityLevelStr());
+        cont->setVerbosity( SALOME::VerbosityActivated(), SALOME::VerbosityLevelStr().c_str() );
         return cont._retn();
       }
       else
@@ -515,9 +559,27 @@ Engines::Container_ptr SALOME_ContainerManager::GiveContainer(const Engines::Con
   return ret;
 }
 
+std::string SALOME_ContainerManager::GetCppBinaryOfKernelSSLContainer() const
+{
+  switch( SALOME::GetPyExecutionMode() )
+  {
+    case SALOME::PyExecutionMode::InProcess:
+      return "SALOME_Container_No_NS_Serv";
+    case SALOME::PyExecutionMode::OutOfProcessNoReplay:
+      return "SALOME_Container_No_NS_Serv_OutProcess";
+    case SALOME::PyExecutionMode::OutOfProcessWithReplay:
+      return "SALOME_Container_No_NS_Serv_OutProcess_Replay";
+    default:
+      {
+        ERROR_MESSAGE("Not manager py execution mode");
+        THROW_SALOME_EXCEPTION("GetCppBinaryOfKernelSSLContainer : Not manager py execution mode");
+      }
+  }
+}
+
 std::string SALOME_ContainerManager::GetCppBinaryOfKernelContainer() const
 {
-  std::string ret = this->_isSSL ? "SALOME_Container_No_NS_Serv" : "SALOME_Container";
+  std::string ret = this->_isSSL ?  GetCppBinaryOfKernelSSLContainer() : "SALOME_Container";
   return ret;
 }
 
@@ -661,8 +723,10 @@ SALOME_ContainerManager::LaunchContainer(const Engines::ContainerParameters& par
         struct stat file_info;
         stat(val, &file_info);
         bool is_dir = S_ISDIR(file_info.st_mode);
-        if (is_dir)logFilename=val;
-        else std::cerr << "SALOME_TMP_DIR environment variable is not a directory use /tmp instead" << std::endl;
+        if (is_dir)
+          logFilename=val;
+        else
+          MESSAGE( "SALOME_TMP_DIR environment variable is not a directory use /tmp instead" << std::endl );
       }
     logFilename += "/";
 #endif
@@ -713,6 +777,7 @@ SALOME_ContainerManager::LaunchContainer(const Engines::ContainerParameters& par
       else
         {
           // Setting log file name
+          ret->locallogfilename( logFilename.c_str() );
           logFilename=":"+logFilename;
           logFilename="@"+Kernel_Utils::GetHostname()+logFilename;//threadsafe
           logFilename=user+logFilename;
@@ -925,18 +990,17 @@ std::string GetCommandFromTemplate(const std::string& theScriptName,
   // manage GIL
 
   PyObject* mod(PyImport_ImportModule(theScriptName.c_str()));
+  MESSAGE("Template name :"<< theScriptName.c_str());
+
   if (!mod)
   {
-    PyObject* sys = PyImport_ImportModule("sys");
-    PyObject* sys_path = PyObject_GetAttrString(sys, "path");
-    PyObject* folder_path = PyUnicode_FromString(getScriptTemplateFilePath().c_str());
+    AutoPyRef sys = PyImport_ImportModule("sys");
+    AutoPyRef sys_path = PyObject_GetAttrString(sys, "path");
+    AutoPyRef folder_path = PyUnicode_FromString(getScriptTemplateFilePath().c_str());
     PyList_Append(sys_path, folder_path);
 
     mod = PyImport_ImportModule(theScriptName.c_str());
 
-    Py_XDECREF(folder_path);
-    Py_XDECREF(sys_path);
-    Py_XDECREF(sys);
   }
 
   if (mod)
@@ -981,6 +1045,10 @@ std::string GetCommandFromTemplate(const std::string& theScriptName,
       Py_XDECREF(mod);
     }
   }
+  else
+  {
+    ERROR_MESSAGE("Can not import the template script \"" << theScriptName << "\" !");
+  }
 
   MESSAGE("Command from template is ... " << command << std::endl);
   return command;
@@ -1058,6 +1126,7 @@ std::string SALOME_ContainerManager::BuildCommandToLaunchLocalContainer(const En
   std::string ompi_uri_file = GetenvThreadSafeAsString("OMPI_URI_FILE");
   script_parameters.push(ompi_uri_file.empty() ? "NULL" : ompi_uri_file);
 
+  MESSAGE("Retrieving command from template (python module) \"" << script_name << "\"" << std::endl);
   std::string command_from_template = GetCommandFromTemplate(script_name, script_parameters);
 
   std::ostringstream o;
@@ -1338,7 +1407,7 @@ std::string SALOME_ContainerManager::BuildTempFileToLaunchRemoteContainer (const
 
   else if (resInfo.Protocol == srun)
     {
-      command = "srun -n 1 -N 1 -s --mem-per-cpu=0 --cpu-bind=none --nodelist=";
+      command = "srun -n 1 -N 1 --overlap --mem-per-cpu=0 --cpu-bind=none --nodelist=";
       std::string commandRcp = "rcp ";
       commandRcp += tmpFileName;
       commandRcp += " ";