Salome HOME
[EDF29576] : Move to python implementation of driver and integrate monitoring into...
authorAnthony Geay <anthony.geay@edf.fr>
Fri, 23 Feb 2024 17:39:25 +0000 (18:39 +0100)
committerAnthony Geay <anthony.geay@edf.fr>
Thu, 7 Mar 2024 10:42:26 +0000 (11:42 +0100)
idl/SALOME_Component.idl
idl/SALOME_ContainerManager.idl
src/Basics/PythonCppUtils.hxx
src/Container/Container_i.cxx
src/Container/SALOME_Container.py
src/Container/SALOME_ContainerManager.cxx
src/Container/SALOME_ContainerManager.hxx
src/Container/SALOME_Container_SignalsHandler.cxx
src/Container/SALOME_Container_i.hxx
src/KERNEL_PY/__init__.py
src/NamingService/NamingService.i

index a2a402d5f61efc867e006bd5c8ad11102808d240..b3585af45a067c565b49780945ba00d207ca7235 100644 (file)
@@ -190,9 +190,12 @@ module Engines
 
     void setVerbosity(in boolean activated, in string level);
 
-    //!  Shutdown the Container process.
+    //!  Shutdown the Container process. Shutdown is not immediate. It waits for all remaining invokation completion.
     void Shutdown();
 
+    //!  Shutdown the Container process. Shutdown is immediate for this method.
+    void ShutdownNow();
+
     //!  Returns the hostname of the container
     string getHostName();
 
index be92c24c01814f2ac153220e905c29d0acde464e..d06c3c06bfea8d8c9db0109aa27f464627c47ded 100644 (file)
@@ -86,8 +86,11 @@ interface ContainerManager
   //! Currently: get, start, getorstart, findorstart, find
   Container GiveContainer(in ContainerParameters params) raises (SALOME::SALOME_Exception);
 
-  //!  Shutdown all containers that have been launched by the container manager
+  //!  Shutdown all containers that have been launched by the container manager. This termination is soft. It means that orb.shutdown is invoked meaning that completion of all CORBA
   void ShutdownContainers();
+  
+  //!  Stronger version than ShutdownContainers. This method does not wait for completion of last CORBA invokation on containers. It terminates them
+  void ShutdownContainersNow();
 
   long GetTimeOutToLaunchServerInSecond();
 
index 9050055668d35be50a9787b9cac813ebfd944faf..8a54b86bb7013ea88693b769e8160dcaae036702 100644 (file)
@@ -34,7 +34,7 @@ class AutoPyRef
 {
 public:
   AutoPyRef(PyObject *pyobj=nullptr):_pyobj(pyobj) { }
-  virtual ~AutoPyRef() { release(); }
+  ~AutoPyRef() { release(); }
   AutoPyRef(const AutoPyRef& other):_pyobj(other._pyobj) { if(_pyobj) Py_XINCREF(_pyobj); }
   AutoPyRef(AutoPyRef&& other) = default;
   AutoPyRef& operator=(const AutoPyRef& other) { if(_pyobj==other._pyobj) return *this; release(); _pyobj=other._pyobj; Py_XINCREF(_pyobj); return *this; }
@@ -55,3 +55,12 @@ public:
   AutoPyRefGilSafe(PyObject *pyobj=nullptr):AutoPyRef(pyobj) { }
   ~AutoPyRefGilSafe() { AutoGIL agil; release(); }
 };
+
+class AutoPyYielder
+{
+private:
+  PyThreadState *_save = nullptr;
+public:
+  AutoPyYielder() { _save = PyEval_SaveThread(); }
+  ~AutoPyYielder() { PyEval_RestoreThread(_save); }
+};
index 872e161ab7c5e9ba19a203975d59d6c4e4cf7166..0ad306bb03a88026596d3a4e4ad0a2c9f86993bb 100644 (file)
@@ -156,7 +156,7 @@ Abstract_Engines_Container_i::Abstract_Engines_Container_i (CORBA::ORB_ptr orb,
 {
   _pid = (long)getpid();
 
-  if(ns)
+  if( isServantAloneInProcess )
     ActSigIntHandler() ;
 
   _argc = argc ;
@@ -708,6 +708,24 @@ CORBA::Long Abstract_Engines_Container_i::getTotalPhysicalMemoryInUseByMe()
 */
 //=============================================================================
 void Abstract_Engines_Container_i::Shutdown()
+{
+  ShutdownCommonPart();
+  if(_isServantAloneInProcess)
+  {
+    MESSAGE("Effective Shutdown of container Begins...");
+    try
+    {
+      if(!CORBA::is_nil(_orb))
+        _orb->shutdown(0);
+    }
+    catch(...)
+    {
+    }
+    MESSAGE("Effective Shutdown of container Ends...");  
+  }
+}
+
+void Abstract_Engines_Container_i::ShutdownCommonPart()
 {
   MESSAGE("Engines_Container_i::Shutdown()");
 
@@ -734,7 +752,7 @@ void Abstract_Engines_Container_i::Shutdown()
     }
   }
   _listInstances_map.clear();
-
+  MESSAGE("Engines_Container_i::Shutdown() -- step 2");
   // NS unregistering may throw in SSL mode if master process hosting SALOME_Embedded_NamingService servant has vanished
   // In this case it's skip it and still continue.
   try
@@ -745,19 +763,28 @@ void Abstract_Engines_Container_i::Shutdown()
   catch(...)
   {
   }
-  //
-  this->cleanAllPyScripts();
-  //
+  MESSAGE("Engines_Container_i::Shutdown() -- step 3");
+  try
   {
-    AutoGIL gstate;
-    AutoPyRef result = PyObject_CallMethod(_pyCont, (char*)"shutdownPy", (char*)"",nullptr);
+    this->cleanAllPyScripts();
+    //
+    {
+      AutoGIL gstate;
+      AutoPyRef result = PyObject_CallMethod(_pyCont, (char*)"shutdownPy", (char*)"",nullptr);
+    }
   }
-  //
-  if(_isServantAloneInProcess)
+  catch(...)
   {
-    MESSAGE("Effective Shutdown of container Begins...");
-    if(!CORBA::is_nil(_orb))
-      _orb->shutdown(0);
+  }
+  MESSAGE("Engines_Container_i::Shutdown() -- step 4");
+}
+
+void Abstract_Engines_Container_i::ShutdownNow()
+{
+  ShutdownCommonPart();if(_isServantAloneInProcess)
+  {
+    AutoGIL gstate;
+    AutoPyRef result = PyObject_CallMethod(_pyCont, (char*)"killMe", (char*)"",nullptr);
   }
 }
 
index 1fa1d41d07668b749ba7385a027aa42823bc11d0..66113499a8c6b5cc3af4376bbf0e9155956e3aeb 100644 (file)
@@ -186,6 +186,10 @@ class SALOME_Container_i:
               #self._log.destroy()# TODO : choose to destroy perf report or not. For the moment we keep the report
               pass
            
+    def killMe(self):
+        import signal
+        os.kill( os.getpid() , signal.SIGTERM)
+           
     def setLogFileName(self, logFileName):
         logging.debug("setLogFileName {} PID = {}".format(logFileName,os.getpid()))
         if getSSLMode():
index d3d36bb7053a3a2a6c30e8f33c60ece7c31ec703..66cd8fd09cf24c3f33eb29229b85cf336fd0f9db 100644 (file)
@@ -241,9 +241,9 @@ void SALOME_ContainerManager::SetDeltaTimeBetweenCPUMemMeasureInMilliSecond(CORB
  */
 //=============================================================================
 
-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();
@@ -289,11 +289,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)
       {
@@ -311,6 +312,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();
index c1d33f9bfa58dcf081c06a6d3610ad0e752bdc9c..330d3ed7c1274a04cb8b8b41e1c394a598004ae1 100644 (file)
@@ -35,6 +35,7 @@
 #include <vector>
 #include <string>
 #include <utility>
+#include <functional>
 #include <set>
 
 class SALOME_NamingService_Abstract;
@@ -52,6 +53,8 @@ public:
 
   void ShutdownContainers() override;
 
+  void ShutdownContainersNow() override;
+
   void SetOverrideEnvForContainers(const Engines::KeyValDict& env) override;
 
   Engines::KeyValDict *GetOverrideEnvForContainers() override;
@@ -77,6 +80,10 @@ public:
 
   static const char *_ContainerManagerNameInNS;
 
+private:
+
+  void ShutdownContainersGeneric(std::function<void(Engines::Container_ptr)> funcToBeCalledOnContainer);
+
 protected:
   // C++ methods
   Engines::Container_ptr
index f3539d41ad1999169c4474f30084eb351c5b6ed7..55b548428e008a20e1ab702f4bae71180842b6f9 100644 (file)
@@ -39,6 +39,7 @@ void HandleServerSideSignals(CORBA::ORB_ptr theORB)
  //  CASCatch_SignalsHandler aSignalsHandler;
   try {
     theORB->run();
+    INFOS("ORB run finished...");
     // CCRT porting
     //  }catch(CORBA::SystemException&){
     //    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
index a86c22af2b9219c3f98020ba0a31bf36a71098ce..9f67a52ce4fc5410d74b26946ff7d41c0f5f7c54 100644 (file)
@@ -124,7 +124,8 @@ public:
   void verbosity(bool& activated, CORBA::String_out level) override;
   void setVerbosity(bool activated, const char *level) override;
 
-  virtual void Shutdown();
+  void Shutdown() override;
+  void ShutdownNow() override;
   char *getHostName();
   CORBA::Long getPID();
   //! Kill current container
@@ -170,6 +171,8 @@ public:
   PortableServer::ObjectId *getCORBAId() const { return _id; }
 public:
   static const int DFT_TIME_INTERVAL_BTW_MEASURE;
+private:
+  void ShutdownCommonPart();
 protected:
   static std::map<std::string, int> _cntInstances_map;
   static std::map<std::string, void *> _library_map;  // library names, loaded
index 4446fdb60ec570d35123c2d53870428e71b98148..61533250055563a1a95e9fa39b7b7f632c71f182 100644 (file)
@@ -272,6 +272,7 @@ def salome_init_without_session(path=None, embedded=False, iorfakensfile=None):
     type(logm).Fetch = LogManagerFetch
     type(logm).DumpInFile = LogManagerDumpInFile
     type(logm).LaunchMonitoringDumpFile = LogManagerLaunchMonitoringDumpFile
+    type(logm).FinalFetchBeforeDying = LogManagerFinalFetchBeforeDying
     type(logm).GetLatestMonitoringDumpFile = LogManagerGetLatestMonitoringDumpFile
     type(logm).DumpIORInFile = LogManagerDumpIORInFile
     #
@@ -283,6 +284,12 @@ def salome_init_without_session(path=None, embedded=False, iorfakensfile=None):
         with open(iorfakensfile,"w") as iorfakensf:
             iorfakensf.write(NamingService.IOROfNS())
     
+CM_NAME_IN_NS = "/ContainerManager"
+RM_NAME_IN_NS = "/ResourcesManager"
+DSM_NAME_IN_NS = "/DataServerManager"
+ESM_NAME_IN_NS = "/ExternalServers"
+LOGM_NAME_IN_NS = "/LogManager"
+
 def salome_init_without_session_attached(path=None, embedded=False):
     """
     Configuration SSL inside a python interpretor launched in the SALOME_Container_No_NS_Serv.
@@ -297,25 +304,20 @@ def salome_init_without_session_attached(path=None, embedded=False):
     import KernelBasis
     nsAbroad = orb.string_to_object( KernelBasis.getIOROfEmbeddedNS() )
     import SALOME
-    CM_NAME_IN_NS = "/ContainerManager"
     cm = orb.string_to_object( nsAbroad.Resolve(CM_NAME_IN_NS).decode() )
     type(cm).SetOverrideEnvForContainersSimple = ContainerManagerSetOverrideEnvForContainersSimple
     naming_service.Register(cm,CM_NAME_IN_NS)
-    RM_NAME_IN_NS = "/ResourcesManager"
     rm = orb.string_to_object( nsAbroad.Resolve(RM_NAME_IN_NS).decode() )
     naming_service.Register(rm,RM_NAME_IN_NS)
     #
     from LifeCycleCORBA import LifeCycleCORBASSL
     lcc = LifeCycleCORBASSL()
-    DSM_NAME_IN_NS = "/DataServerManager"
     dsm = orb.string_to_object( nsAbroad.Resolve(DSM_NAME_IN_NS).decode() )
     naming_service.Register(dsm,DSM_NAME_IN_NS)
     #
-    ESM_NAME_IN_NS = "/ExternalServers"
     esm = orb.string_to_object( nsAbroad.Resolve(ESM_NAME_IN_NS).decode() )
     naming_service.Register(esm,ESM_NAME_IN_NS)
     #
-    LOGM_NAME_IN_NS = "/LogManager"
     logm = orb.string_to_object( nsAbroad.Resolve(LOGM_NAME_IN_NS).decode() )
     naming_service.Register(logm,LOGM_NAME_IN_NS)
 
@@ -567,6 +569,12 @@ def LogManagerLoadFromIORFile( iorFile ):
         tempFileName = f.name
     return LoadAndWrite( logm, tempFileName )
 
+def LogManagerFinalFetchBeforeDying(self):
+    import shutil
+    a,b = self.getFileNamePairOfLogger()
+    self.DumpInFile( b )
+    shutil.move( b, a)
+
 def LogManagerGetLatestMonitoringDumpFile(self):
     import shutil
     import logging
@@ -580,14 +588,16 @@ def LogManagerGetLatestMonitoringDumpFile(self):
         logging.debug("LogManagerGetLatestMonitoringDumpFile SITUATION A")
         if os.path.exists( b ):
             os.remove( b )
+        self.FinalFetchBeforeDying()
         return a
     if lastVersion == b:
         logging.debug("LogManagerGetLatestMonitoringDumpFile SITUATION B")
         if os.path.exists( b ):
             shutil.move( b, a)
+        self.FinalFetchBeforeDying()
         return a
     logging.warning("in LogManagerGetLatestMonitoringDumpFile an unexpected situation araises.")
     return ""
 
 #to expose all objects to pydoc
-__all__=dir()
+__all__ = dir()
index f63aba017891063f716019945c158b5c3ec3df8d..308588a3fbf22d35cca8c1850ece109a049428d7 100644 (file)
@@ -141,6 +141,15 @@ def NamingService_DumpIORInFile(cls,iorFileName):
   with open( iorFileName, "w" ) as f:
     f.write( cls.IOROfNS() )
 NamingService.DumpIORInFile = classmethod(NamingService_DumpIORInFile)
+def NamingService_LoadIORInFile(cls,iorFileName):
+  import Engines
+  import CORBA
+  orb=CORBA.ORB_init([''])
+  with open( iorFileName ) as f:
+    ior = f.read()
+  ref = orb.string_to_object(ior)
+  return ref
+NamingService.LoadIORInFile = classmethod( NamingService_LoadIORInFile )
 def NamingService_KillContainersInFile(cls,logFileName):
   import Engines
   import CORBA